我需要修改一个xml文件(实际上是一个.rdlc报告文件)并添加一些有很多子节点的节点(并且这些子节点又有子节点)。其实他们几乎是相同的结构,像这样:在.Net中添加一堆节点的xml节点的最简单方法?
<TablixRow>
<Height>0.23622in</Height>
<TablixCells>
<TablixCell>
<CellContents>
<Textbox Name="Textbox1">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value/>
<Style/>
</TextRun>
</TextRuns>
<Style/>
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox1</rd:DefaultName>
<Style>
<Border>
<Style>None</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
<TablixCell>
<CellContents>
<Textbox Name="Textbox5">
<CanGrow>true</CanGrow>
<KeepTogether>true</KeepTogether>
<Paragraphs>
<Paragraph>
<TextRuns>
<TextRun>
<Value/>
<Style/>
</TextRun>
</TextRuns>
<Style/>
</Paragraph>
</Paragraphs>
<rd:DefaultName>Textbox5</rd:DefaultName>
<Style>
<Border>
<Style>None</Style>
</Border>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
</Textbox>
</CellContents>
</TablixCell>
</TablixCells>
</TablixRow>
那么最简单的方法是什么?在正常情况下,我只是创建一个XmlNode和一些XmlAttribute对象,将这些属性附加到该节点,并以相同的方式创建子节点,最后将每个子节点追加到其父节点中。不用说,处理我的示例节点会很乏味。有没有更简单的方法来做到这一点?和类XmlDocument一样,函数LoadXml(xml作为字符串),将字符串作为整个xml文件并构建结构体。有没有类似的方法来构造一个XmlNode对象?所以我只需要提供表示我节点的整个字符串,然后导航到需要更改值的子节点。谢谢!
更新: 我正在使用VB.NET。使用XElement时,命名空间有一个问题。在这个链接 XName Class中,它表示对于C#,建议只使用overriden add操作符来组合元素和NS,但对于VB,它建议在顶部使用Import(在Module之外的示例中,我假设它也应该为Class工作),然后一切都会自动使用这个NS。然而,这种情况并非如此。例如,如果我给
Dim para As XElement = _
<ReportParameter Name="HasErr">
<DataType>Boolean</DataType>
<DefaultValue>
<Values>
<Value>False</Value>
</Values>
</DefaultValue>
<Prompt>ReportParameter1</Prompt>
</ReportParameter>
它会自动将我指定的(并声明为默认)NS在那里。但是,如果我使用XElement.Parse(xml As String),其中xml是表示xml的相同字符串,它将不会添加此NS,最终将使用空NS(我想使用XElement的原因。解析是我想给我的自定义参数值,如& MY_TYPE_NAME &)。 第二个问题使用@JohnD的代码的时候是,我尝试
xdoc.Root.Elements("ReportParameters").FirstOrDefault()
,我认为也将用我的声明和默认NS,将返回任何结果,即,它会搜索空命名空间内,但它实际上是在NS我提到。
任何人都知道这是MS为什么没有XName类的构造函数的原因,我可以在使用它之前指定一个名称空间?它说,只有一个隐含的转换,所以在
xdoc.Root.Elements("ReportParameters")
给代表元素名称的字符串时,它会隐生成一个XName的对象添加到索引中的元素的搜索。但它真的很笨拙。
最新更新: 我现在发现解决方案来解决我的更新中的第一个问题:我现在使用XML文字来创建XElement,并且可以在其中使用表达式。所以它现在看起来像这样:
Dim paraDefNode As XElement = _
<ReportParameter Name=<%= para.Value %>>
<DataType>String</DataType>
<DefaultValue>
<Values>
<Value>False</Value>
</Values>
</DefaultValue>
<Prompt>ReportParameter1</Prompt>
</ReportParameter>
它会添加我指定的NS。 (就像我说的,XElement.Parse(字符串)不会添加它)所以现在我可以构造正确的节点。对于我的第二个问题,我仍然无法弄清楚:我无法使用元素名称导航到目标节点,因为它不会搜索正确的NS。
无论如何,我会将@JohnD的帖子标记为答案,因为他建议使用LINQ to XML。
感谢您的回复,您的回答很明确,但我正在努力争取名称空间。首先,当我使用代码'xdoc.Root.Elements(“MY_ELEMENT_NAME”)。FirstOrDefault()'时,它不返回任何内容。我猜它与命名空间有关,我需要为这个XName对象指定命名空间来进行搜索。可悲的是,我找不到任何例子。此链接:[链接](http://msdn.microsoft.com/en-us/library/system.xml.linq.xname.aspx#Y1999)没有给出如何使用XName对象的示例代码中间。 – tete
其次,我想我还需要指定要添加的XElement的名称空间(在您的示例中,对于xelementToAdd),如果它位于一个NS下,我是否正确?谢谢! – tete
您可以发布您尝试插入的XML片段吗? (使用MY_ELEMENT_NAME的人)? – JohnD