2011-09-28 96 views
0

我有幾個XML文檔,它們都具有相同的結構(元素名稱,屬性名稱和層次結構)。如何在XmlDocument中處理XML中的命名空間c#

但是,某些元素和屬性在每個XML文檔中都有自定義名稱空間,這些名稱空間在設計時不爲人所知。他們改變,不要問...

如何使用一組XPath遍歷文檔時如何處理?

我應該在處理之前刪除所有的命名空間嗎?

我可以使用XmlNamespaceManager自動註冊所有名稱空間嗎?

有什麼想法?

更新:一些例子(爲了清楚省略了命名空間聲明):

<root> 
    <child attr="val" /> 
</root> 

<root> 
    <x:child attr="val" /> 
</root> 

<root> 
    <y:child z:attr="val" /> 
</root> 

感謝

+0

命名空間或前綴?如果前綴 - 無需執行任何操作,如果名稱空間 - 使用XmlNamespaceManager註冊將不會有任何好處,因爲您不能提前創建XPath而不知道名稱空間。有關使用本地名稱的解答可能是最好的方法。 –

回答

1

我相信你會發現在這個線程#1

XPath + Namespace Driving me crazy

一些很好的啓示

在我看來你有兩種解決方案之一:

1-如果所有可能的命名空間是前手知道,那麼你就可以在你的XmlNamespaceManager解析開始

2-使用XPath命名空間無關的選擇

當然之前註冊所有這些你總是可以從任何內聯命名空間中清理xml文檔,並在沒有命名空間的情況下開始在一個乾淨的uniorm xml上進行解析..但老實說,我不認爲增加這個開銷步驟會帶來收益。

2

假設你有以下的XML:

<root xmlns="first"> 
    <el1 xmlns="second"> 
    <el2 xmlns="third">... 

你可以寫你的查詢忽略以下方式命名空間: /*[local-name()='root']/*[local-name()='el1']/*[local-name()='el2'] 等 當然你也可以遍歷整個文檔以獲得命名空間和負載他們到nsmanager。但是通常情況下,這會導致您評估文檔中的每個節點。在這種情況下,將文檔視爲對象樹並且不使用XPath會更快。

+0

這看起來像答案,特別是因爲命名空間前綴是不同的 –

0

Scott Hanselman有關於提取XML文檔中所有XML命名空間的nice article。據推測,當你得到所有的XML命名空間時,你可以遍歷所有的命名空間管理器。

0

你可以嘗試這樣的事情剝離的命名空間:

//Implemented based on interface, not part of algorithm 
public string RemoveAllNamespaces(string xmlDocument) 
{ 
    return RemoveAllNamespaces(XElement.Parse(xmlDocument)).ToString();  
} 

//Core recursion function 
private XElement RemoveAllNamespaces(XElement xmlDocument) 
{ 
    if (!xmlDocument.HasElements) 
    { 
     XElement xElement = new XElement(xmlDocument.Name.LocalName); 
     xElement.Value = xmlDocument.Value; 
     return xElement; 
    } 
    return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el))); 
} 

見彼得Stegnar的回答此處瞭解詳情:
How to remove all namespaces from XML with C#?

0

您還可以使用直接節點測試使用通配符,這將匹配任何名稱空間(或缺少名稱空間):

$your-document/*:root/*:child/@*:attr