我正在使用XElement来操作我的xml文件:找到目标节点,然后向其添加子节点。但现在我有一个问题。假设我的xml文件如下所示:
<Report xmlns="MY_NAMESPACE"
<Width>100</Width>
<Height>100</Height>
<ReportItems>
<ReportItem>
...
</Report>
我想使用VB.NET向<ReportItem>
节点添加新的<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)
现在有问题:如果我在查询Root元素时没有指定"{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),但是现在它添加不必要的东西这一定是开玩笑吧!
答案 0 :(得分:2)
我遇到了类似的问题,我的解决方案是在保存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
您也可以使用具有OmitDuplicates的SaveOptions参数调用XDocument.Save。