我想解析一些標準的XML文檔,它們使用來自各種來源的名爲MARCXML的模式。如何正確解析具有任意名稱空間的XML文檔
下面是需要處理的一個示例XML文件的前幾行...
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<marc:collection xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
<marc:record>
<marc:leader>00925njm 22002777a 4500</marc:leader>
,一個沒有命名空間前綴...
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<collection xmlns="http://www.loc.gov/MARC21/slim">
<record>
<leader>01142cam 2200301 a 4500</leader>
關鍵點:爲了讓XPath在程序中進一步解決,我必須通過一個正則表達式例程來將名稱空間添加到NameTable(默認情況下不會添加它們)。這對我來說似乎沒有必要。
Regex xmlNamespace = new Regex("xmlns:(?<PREFIX>[^=]+)=\"(?<URI>[^\"]+)\"", RegexOptions.Compiled);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlRecord);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDoc.NameTable);
MatchCollection namespaces = xmlNamespace.Matches(xmlRecord);
foreach (Match n in namespaces)
{
nsMgr.AddNamespace(n.Groups["PREFIX"].ToString(), n.Groups["URI"].ToString());
}
中的XPath調用看起來是這樣的......
XmlNode leaderNode = xmlDoc.SelectSingleNode(".//" + LeaderNode, nsMgr);
凡LeaderNode
是一個可配置的值,並會在第二個例子中等於第一個例子"marc:leader"
和"leader"
。
有沒有更好,更有效的方法來做到這一點?注意:對於使用LINQ解決此問題的建議值得歡迎,但我主要想知道如何使用XmlDocument
解決此問題。
編輯:我把GrayWizardx的建議,現在有以下代碼...
if (LeaderNode.Contains(":"))
{
string prefix = LeaderNode.Substring(0, LeaderNode.IndexOf(':'));
XmlNode root = xmlDoc.FirstChild;
string nameSpace = root.GetNamespaceOfPrefix(prefix);
nsMgr.AddNamespace(prefix, nameSpace);
}
現在有正則表達式上沒有更多的依賴!
我面臨幾乎完全相同的問題。你如何完成你的'LeaderNode'魔法?你有預知你正在處理什麼記錄類型? – 2014-02-05 16:28:48