2011-11-04 125 views
0

我正在使用XElement來操作我的xml文件:查找目標節點,然後向其中添加子節點。但是現在我有一個問題。比方說,我的XML文件看起來像這樣:XElement.Add(XElement)會自動將名稱空間添加到子節點?

<Report xmlns="MY_NAMESPACE" 
    <Width>100</Width> 
    <Height>100</Height> 
    <ReportItems> 
    <ReportItem> 
... 
</Report> 

而且我想一個新的<ReportItem>添加到使用VB.NET的<ReportItems>節點。在這個鏈接How to: Create a Document with Namespaces (LINQ to XML) (Visual Basic)它說,爲了聲明和使用名稱空間,它需要在文件的開頭導入它們(它不同於C#的用法)。所以我做Imports <xmlns="MY_NAMESPACE">。現在我需要1)首先找到<ReportItems>節點,並且2)添加我的新節點。爲了做到的第一步,我想

Dim xmldoc = XDocument.Load(MY_XML_FILE_PATH) 
Dim target = xmldoc.Root.Elements("{MY_NAMESPACE}" & "ReportItems").FirstOrDefault 

而要做到步驟2),我做了

Dim newNode As XElement = _ 
    <ReportItem/> 
target.Add(newNode) 

現在有這個問題:如果我不指定"{MY_NAMESPACE}"當我查詢根元素,我根本找不到ReportItems。這是因爲該字符串實際上用於隱式構造一個XName對象(上帝知道爲什麼我不能明確地將NS分配給XName對象),並且此對象用於搜索。如果我不提供大括號部分,它將在空名稱空間內進行搜索,因此它無法找到位於MY_NAMESPACE中的<ReportItems>節點。但是,如果我給這個大括號的命名空間,最後的XML文件看起來像這樣:

<Report xmlns="MY_NAMESPACE" 
    <Width>100</Width> 
    <Height>100</Height> 
    <ReportItems> 
    <ReportItem> 
    <ReportItem xmlns="MY_NAMESPACE">  
... 
</Report> 

第二<ReportItem>是新添加的一個,但可悲的是,這不是一個有效的文件(我的解析器在抱怨進一步處理xml文件)。那麼,如何讓這個新項目看起來與現有的項目完全一樣,沒有任何名稱空間?這一直讓我瘋狂。我花了一整天的時間來弄清楚,我需要添加大括號,以便它可以找到目標節點(它不起作用,就像上面的鏈接說的那樣,它會自動添加並搜索默認的NS),但現在它增加了一些不必要這是在開玩笑吧!

回答

1

我也有類似的問題,我的解決方案是保存XML時,可以省略重複的命名空間:

Dim sb As New StringBuilder() 
Dim settings As XmlWriterSettings = New XmlWriterSettings() 
settings.NamespaceHandling = NamespaceHandling.OmitDuplicates 

Using writer As XmlWriter = XmlWriter.Create(sb, settings) 
    Dim xdoc As XDocument = WriteDocument() 
    xdoc.Save(writer) 
End Using 

您也可以撥打XDocument.Save用具有OmitDuplicates以及SaveOptions參數。

+1

XDocument.CreateReader方法也支持此功能。 「xDocument.CreateReader(ReaderOptions.OmitDuplicateNamespaces)」 –

相關問題