File indexing completed on 2024-04-21 03:41:35
0001 /* 0002 SPDX-FileCopyrightText: 2005, 2006 Carsten Niehaus <cniehaus@kde.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "elementparser.h" 0007 0008 #include "chemicaldataobject.h" 0009 #include "element.h" 0010 0011 0012 #include <KLocalizedString> 0013 #include <KUnitConversion/Converter> 0014 0015 class ElementSaxParser::Private 0016 { 0017 public: 0018 Private() 0019 : currentUnit(KUnitConversion::NoUnit) 0020 , currentElement(nullptr) 0021 , inElement(false) 0022 , inName(false) 0023 , inMass(false) 0024 , inExactMass(false) 0025 , inAtomicNumber(false) 0026 , inSymbol(false) 0027 , inIonization(false) 0028 , inElectronAffinity(false) 0029 , inElectronegativityPauling(false) 0030 , inRadiusCovalent(false) 0031 , inRadiusVDW(false) 0032 , inBoilingPoint(false) 0033 , inMeltingPoint(false) 0034 , inPeriodTableBlock(false) 0035 , inNameOrigin(false) 0036 , inDiscoveryDate(false) 0037 , inDiscoverers(false) 0038 , inPeriod(false) 0039 , inCrystalstructure(false) 0040 , inAcidicbehaviour(false) 0041 , inFamily(false) 0042 , inGroup(false) 0043 , inElectronicconfiguration(false) 0044 , inDangerSymbol(false) 0045 , inRPhrase(false) 0046 , inSPhrase(false) 0047 , inCountry(false) 0048 , inOxidation(false) 0049 { 0050 } 0051 0052 ~Private() 0053 { 0054 delete currentElement; 0055 // qDeleteAll(elements); 0056 } 0057 0058 ChemicalDataObject currentDataObject; 0059 int currentUnit; // KUnitConversion::UnitId 0060 Element *currentElement = nullptr; 0061 0062 QList<Element *> elements; 0063 0064 bool inElement; 0065 bool inName; 0066 bool inMass; 0067 bool inExactMass; 0068 bool inAtomicNumber; 0069 bool inSymbol; 0070 bool inIonization; 0071 bool inElectronAffinity; 0072 bool inElectronegativityPauling; 0073 bool inRadiusCovalent; 0074 bool inRadiusVDW; 0075 bool inBoilingPoint; 0076 bool inMeltingPoint; 0077 bool inPeriodTableBlock; 0078 bool inNameOrigin; 0079 bool inDiscoveryDate; 0080 bool inDiscoverers; 0081 bool inPeriod; 0082 bool inCrystalstructure; 0083 bool inAcidicbehaviour; 0084 bool inFamily; 0085 bool inGroup; 0086 bool inElectronicconfiguration; 0087 bool inDangerSymbol; 0088 bool inRPhrase; 0089 bool inSPhrase; 0090 bool inCountry; 0091 bool inOxidation; 0092 }; 0093 0094 ElementSaxParser::ElementSaxParser() 0095 : QXmlDefaultHandler() 0096 , d(new Private) 0097 { 0098 } 0099 0100 ElementSaxParser::~ElementSaxParser() 0101 { 0102 delete d; 0103 } 0104 0105 bool ElementSaxParser::startElement(const QString &, const QString &localName, const QString &, const QXmlAttributes &attrs) 0106 { 0107 if (localName == QLatin1String("atom")) { 0108 d->currentElement = new Element(); 0109 d->inElement = true; 0110 } else if ((d->inElement && localName == QLatin1String("scalar")) || localName == QLatin1String("array")) { 0111 for (int i = 0; i < attrs.length(); ++i) { 0112 if (attrs.localName(i) == QLatin1String("units")) { 0113 // qCDebug(KALZIUM_LIBSCIENCE_LOG) << "value of the unit: " << attrs.value(i); 0114 d->currentUnit = unit(attrs.value(i)); 0115 // qCDebug(KALZIUM_LIBSCIENCE_LOG) << "Took " << d->currentUnit; 0116 continue; 0117 } 0118 0119 if (attrs.value(i) == QLatin1String("bo:atomicNumber")) { 0120 d->inAtomicNumber = true; 0121 } else if (attrs.value(i) == QLatin1String("bo:mass")) { 0122 d->inMass = true; 0123 } else if (attrs.value(i) == QLatin1String("bo:exactMass")) { 0124 d->inExactMass = true; 0125 } else if (attrs.value(i) == QLatin1String("bo:ionization")) { 0126 d->inIonization = true; 0127 } else if (attrs.value(i) == QLatin1String("bo:electronAffinity")) { 0128 d->inElectronAffinity = true; 0129 } else if (attrs.value(i) == QLatin1String("bo:electronegativityPauling")) { 0130 d->inElectronegativityPauling = true; 0131 } else if (attrs.value(i) == QLatin1String("bo:radiusCovalent")) { 0132 d->inRadiusCovalent = true; 0133 } else if (attrs.value(i) == QLatin1String("bo:radiusVDW")) { 0134 d->inRadiusVDW = true; 0135 } else if (attrs.value(i) == QLatin1String("bo:meltingpoint")) { 0136 d->inMeltingPoint = true; 0137 } else if (attrs.value(i) == QLatin1String("bo:boilingpoint")) { 0138 d->inBoilingPoint = true; 0139 } else if (attrs.value(i) == QLatin1String("bo:periodTableBlock")) { 0140 d->inPeriodTableBlock = true; 0141 } else if (attrs.value(i) == QLatin1String("bo:nameOrigin")) { 0142 d->inNameOrigin = true; 0143 } else if (attrs.value(i) == QLatin1String("bo:discoveryDate")) { 0144 d->inDiscoveryDate = true; 0145 } else if (attrs.value(i) == QLatin1String("bo:discoverers")) { 0146 d->inDiscoverers = true; 0147 } else if (attrs.value(i) == QLatin1String("bo:discoveryCountry")) { 0148 d->inCountry = true; 0149 } else if (attrs.value(i) == QLatin1String("bo:period")) { 0150 d->inPeriod = true; 0151 } else if (attrs.value(i) == QLatin1String("bo:crystalstructure")) { 0152 d->inCrystalstructure = true; 0153 } else if (attrs.value(i) == QLatin1String("bo:acidicbehaviour")) { 0154 d->inAcidicbehaviour = true; 0155 } else if (attrs.value(i) == QLatin1String("bo:family")) { 0156 d->inFamily = true; 0157 } else if (attrs.value(i) == QLatin1String("bo:group")) { 0158 d->inGroup = true; 0159 } else if (attrs.value(i) == QLatin1String("bo:electronicConfiguration")) { 0160 d->inElectronicconfiguration = true; 0161 } else if (attrs.value(i) == QLatin1String("bo:dangerSymbol")) { 0162 d->inDangerSymbol = true; 0163 } else if (attrs.value(i) == QLatin1String("bo:RPhrase")) { 0164 d->inRPhrase = true; 0165 } else if (attrs.value(i) == QLatin1String("bo:SPhrase")) { 0166 d->inSPhrase = true; 0167 } else if (attrs.value(i) == QLatin1String("bo:oxidation")) { 0168 d->inOxidation = true; 0169 } 0170 } 0171 } else if (d->inElement && localName == QLatin1String("label")) { 0172 for (int i = 0; i < attrs.length(); ++i) { 0173 if (attrs.localName(i) != QLatin1String("dictRef")) { 0174 continue; 0175 } 0176 0177 if (attrs.value(i) == QLatin1String("bo:symbol")) { 0178 for (int i = 0; i < attrs.length(); ++i) { 0179 if (attrs.localName(i) == QLatin1String("value")) { 0180 d->currentDataObject.setData(attrs.value(i)); 0181 d->currentDataObject.setType(ChemicalDataObject::symbol); 0182 0183 if (d->currentElement) { 0184 d->currentElement->addData(d->currentDataObject); 0185 } 0186 } 0187 } 0188 } else if (attrs.value(i) == QLatin1String("bo:name")) { 0189 for (int i = 0; i < attrs.length(); ++i) { 0190 if (attrs.localName(i) == QLatin1String("value")) { 0191 d->currentDataObject.setData(i18n(attrs.value(i).toUtf8().constData())); 0192 d->currentDataObject.setType(ChemicalDataObject::name); 0193 0194 if (d->currentElement) { 0195 d->currentElement->addData(d->currentDataObject); 0196 } 0197 } 0198 } 0199 } 0200 } 0201 } 0202 return true; 0203 } 0204 0205 bool ElementSaxParser::endElement(const QString &, const QString &localName, const QString &) 0206 { 0207 if (localName == QLatin1String("atom")) { 0208 if (d->currentElement->dataAsString(ChemicalDataObject::symbol) != QLatin1String("Xx")) { 0209 d->elements.append(d->currentElement); 0210 } else { 0211 delete d->currentElement; 0212 } 0213 0214 d->currentElement = nullptr; 0215 d->inElement = false; 0216 } else if (localName == QLatin1String("scalar") || localName == QLatin1String("label") || localName == QLatin1String("array")) { 0217 d->currentDataObject.setUnit(d->currentUnit); 0218 } 0219 return true; 0220 } 0221 0222 bool ElementSaxParser::characters(const QString &ch) 0223 { 0224 d->currentDataObject = ChemicalDataObject(); 0225 ChemicalDataObject::BlueObelisk type; 0226 QVariant value; 0227 0228 if (d->inMass) { 0229 value = ch.toDouble(); 0230 type = ChemicalDataObject::mass; 0231 d->inMass = false; 0232 } else if (d->inExactMass) { 0233 value = ch.toDouble(); 0234 type = ChemicalDataObject::exactMass; 0235 d->inExactMass = false; 0236 } else if (d->inAtomicNumber) { 0237 value = ch.toInt(); 0238 type = ChemicalDataObject::atomicNumber; 0239 d->inAtomicNumber = false; 0240 } else if (d->inIonization) { 0241 value = ch.toDouble(); 0242 ; 0243 type = ChemicalDataObject::ionization; 0244 d->inIonization = false; 0245 } else if (d->inElectronAffinity) { 0246 value = ch.toDouble(); 0247 type = ChemicalDataObject::electronAffinity; 0248 d->inElectronAffinity = false; 0249 } else if (d->inElectronegativityPauling) { 0250 value = ch.toDouble(); 0251 type = ChemicalDataObject::electronegativityPauling; 0252 d->inElectronegativityPauling = false; 0253 } else if (d->inRadiusCovalent) { 0254 value = ch.toDouble(); 0255 type = ChemicalDataObject::radiusCovalent; 0256 d->inRadiusCovalent = false; 0257 } else if (d->inRadiusVDW) { 0258 value = ch.toDouble(); 0259 type = ChemicalDataObject::radiusVDW; 0260 d->inRadiusVDW = false; 0261 } else if (d->inMeltingPoint) { 0262 value = ch.toDouble(); 0263 type = ChemicalDataObject::meltingpoint; 0264 d->inMeltingPoint = false; 0265 } else if (d->inBoilingPoint) { 0266 value = ch.toDouble(); 0267 type = ChemicalDataObject::boilingpoint; 0268 d->inBoilingPoint = false; 0269 } else if (d->inPeriodTableBlock) { 0270 value = ch; 0271 type = ChemicalDataObject::periodTableBlock; 0272 d->inPeriodTableBlock = false; 0273 } else if (d->inNameOrigin) { 0274 value = i18n(ch.toUtf8().constData()); 0275 type = ChemicalDataObject::nameOrigin; 0276 d->inNameOrigin = false; 0277 } else if (d->inDiscoveryDate) { 0278 value = ch.toInt(); 0279 type = ChemicalDataObject::date; 0280 d->inDiscoveryDate = false; 0281 } else if (d->inDiscoverers) { 0282 value = ch; 0283 type = ChemicalDataObject::discoverers; 0284 d->inDiscoverers = false; 0285 } else if (d->inPeriod) { 0286 value = ch.toInt(); 0287 type = ChemicalDataObject::period; 0288 d->inPeriod = false; 0289 } else if (d->inCrystalstructure) { 0290 value = ch; 0291 type = ChemicalDataObject::crystalstructure; 0292 d->inCrystalstructure = false; 0293 } else if (d->inAcidicbehaviour) { 0294 value = ch.toInt(); 0295 type = ChemicalDataObject::acidicbehaviour; 0296 d->inAcidicbehaviour = false; 0297 } else if (d->inFamily) { 0298 value = ch; 0299 type = ChemicalDataObject::family; 0300 d->inFamily = false; 0301 } else if (d->inGroup) { 0302 value = ch.toInt(); 0303 type = ChemicalDataObject::group; 0304 d->inGroup = false; 0305 } else if (d->inElectronicconfiguration) { 0306 value = ch; 0307 type = ChemicalDataObject::electronicConfiguration; 0308 d->inElectronicconfiguration = false; 0309 } else if (d->inDangerSymbol) { 0310 value = ch; 0311 type = ChemicalDataObject::dangerSymbol; 0312 d->inDangerSymbol = false; 0313 } else if (d->inRPhrase) { 0314 value = ch; 0315 type = ChemicalDataObject::RPhrase; 0316 d->inRPhrase = false; 0317 } else if (d->inSPhrase) { 0318 value = ch; 0319 type = ChemicalDataObject::SPhrase; 0320 d->inSPhrase = false; 0321 } else if (d->inCountry) { 0322 if (ch == QLatin1String("ancient")) { 0323 value = 0; 0324 type = ChemicalDataObject::date; 0325 } else { 0326 value = ch; 0327 type = ChemicalDataObject::discoveryCountry; 0328 } 0329 d->inCountry = false; 0330 } else if (d->inOxidation) { 0331 value = ch; 0332 type = ChemicalDataObject::oxidation; 0333 d->inOxidation = false; 0334 } else { // it is a non known value. Do not create a wrong object but return 0335 return true; 0336 } 0337 0338 d->currentDataObject.setData(value); 0339 d->currentDataObject.setType(type); 0340 d->currentDataObject.setUnit(d->currentUnit); 0341 0342 if (d->currentElement) { 0343 d->currentElement->addData(d->currentDataObject); 0344 } 0345 0346 return true; 0347 } 0348 0349 int ElementSaxParser::unit(const QString &unit) const 0350 { 0351 if (unit == QLatin1String("siUnits:kelvin")) { 0352 return KUnitConversion::Kelvin; 0353 } else if (unit == QLatin1String("units:ev")) { 0354 return KUnitConversion::Electronvolt; 0355 } else if (unit == QLatin1String("units:ang")) { 0356 return KUnitConversion::Angstrom; 0357 } else if (unit == QLatin1String("bo:noUnit")) { 0358 return KUnitConversion::NoUnit; 0359 } else { 0360 return KUnitConversion::NoUnit; 0361 } 0362 } 0363 0364 QList<Element *> ElementSaxParser::getElements() const 0365 { 0366 return d->elements; 0367 }