我想使用xerces-c爲了解析一個相當大量的從StarUML生成的XML文檔來改變一些東西,但是我遇到了問題讓xpath查詢因爲它不斷崩潰。Xerces,xpaths和XML命名空間
爲了簡化事情,我打出了文件的一部分轉化爲測試一個較小的XML文件,它看起來像這樣:
<?xml version="1.0" encoding="utf-8"?>
<XPD:UNIT xmlns:XPD="http://www.staruml.com" version="1">
<XPD:HEADER>
<XPD:SUBUNITS>
</XPD:SUBUNITS>
</XPD:HEADER>
<XPD:BODY>
<XPD:OBJ name="Attributes[3]" type="UMLAttribute" guid="onMjrHQ0rUaSkyFAWtLzKwAA">
<XPD:ATTR name="StereotypeName" type="string">ConditionInteraction</XPD:ATTR>
</XPD:OBJ>
</XPD:BODY>
</XPD:UNIT>
所有我想這個例子做的是找到所有的XPD:OBJ
元素,其中只有一個。這個問題似乎源於嘗試使用命名空間進行查詢。當我通過一個非常簡單的xpath查詢XPD:OBJ
它會崩潰,但如果我只通過OBJ
它不會崩潰,但它不會找到XPD:OBJ
元素。
我認爲有一些重要的屬性或設置,我在初始化期間缺少我需要設置,但我不知道它可能是什麼。我查瞭解與命名空間有關的解析器的所有屬性,並啓用了我可以的解析器的所有屬性,但它根本沒有幫助,所以我完全陷入了困境。初始化代碼看起來是這樣的,有很多的事情顯然刪除:
const tXercesXMLCh tXMLManager::kDOMImplementationFeatures[] =
{
static_cast<tXercesXMLCh>('L'),
static_cast<tXercesXMLCh>('S'),
static_cast<tXercesXMLCh>('\0')
};
// Instantiate the DOM parser.
fImplementation = static_cast<tXercesDOMImplementationLS *>(tXercesDOMImplementationRegistry::getDOMImplementation(kDOMImplementationFeatures));
if (fImplementation != nullptr)
{
fParser = fImplementation->createLSParser(tXercesDOMImplementationLS::MODE_SYNCHRONOUS, nullptr);
fConfig = fParser->getDomConfig();
// Let the validation process do its datatype normalization that is defined in the used schema language.
//fConfig->setParameter(tXercesXMLUni::fgDOMDatatypeNormalization, true);
// Ignore comments and whitespace so we don't get extra nodes to process that just waste time.
fConfig->setParameter(tXercesXMLUni::fgDOMComments, false);
fConfig->setParameter(tXercesXMLUni::fgDOMElementContentWhitespace, false);
// Setup some properties that look like they might be required to get namespaces to work but doesn't seem to help at all.
fConfig->setParameter(tXercesXMLUni::fgXercesUseCachedGrammarInParse, true);
fConfig->setParameter(tXercesXMLUni::fgDOMNamespaces, true);
fConfig->setParameter(tXercesXMLUni::fgDOMNamespaceDeclarations, true);
// Install our custom error handler.
fConfig->setParameter(tXercesXMLUni::fgDOMErrorHandler, &fErrorHandler);
}
然後後來我解析文檔,找到根節點,然後運行XPath查詢找到我想要的節點。我離開了大頭說,只是告訴你在哪裏,我的情況下運行XPath查詢有一些明顯錯誤有:
tXercesDOMDocument * doc; // Comes from parsing the file.
tXercesDOMNode * contextNode; // This is the root node retrieved from the document.
tXercesDOMXPathResult * xPathResult;
doc->evaluate("XPD:OBJ", contextNode, nullptr, tXercesDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE), xPathResult);
到evaluate()
的調用是它崩潰某處深裏面的Xerces,我看不清楚,但從我所看到的有很多東西看起來被刪除或未初始化,所以我不確定究竟是什麼原因導致了崩潰。
那麼在這裏有什麼東西看起來明顯錯誤或缺失,這是使xerces使用XML名稱空間所必需的嗎?