2010-10-20 63 views
7

我想解析一些標準的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); 
} 

現在有正則表達式上沒有更多的依賴!

+0

我面臨幾乎完全相同的問題。你如何完成你的'LeaderNode'魔法?你有預知你正在處理什麼記錄類型? – 2014-02-05 16:28:48

回答

2

如果您知道有將是文檔中的給定元素(例如根元素),你可以嘗試使用GetNamespaceOfPrefix

+0

這看起來很有希望。我會試一試:) – 2010-10-20 22:50:07

+0

我瞭解命名空間的方式,它們可以在文檔中的任何位置聲明。你能否抽象出這個方法來處理這個一般情況? – 2014-02-05 16:31:52

+0

@Patrick M我不確定是否誠實。我的理解是,他們必須在文檔的根元素上定義,但可能會添加到任何父元素。我沒有看過這一段時間。 – GrayWizardx 2014-02-06 18:41:15

相關問題