c# - 将多个相似的 XML 节点附加到 XML 文档

标签 c# xml

我目前正在处理一个 XML 请求,并且正在尝试创建一个在调用中具有多个同名子节点的回复文档,因此我要返回的是:

<Reply Document>
    <ConfirmationItem name = "One">
         <ItemDetail />
    </ConfirmationItem>
    <ConfirmationItem name = "Two">
         <ItemDetail />
    </ConfirmationItem>
    ...
    <ConfirmationItem name = "Twenty">
         <ItemDetail />
    </ConfirmationItem>
</Reply Document> 

我做了一些研究,发现了这个线程:XmlReader AppendChild is not appending same child value其中接受的答案是 OP 必须创建新元素才能附加到末尾而不是覆盖第一个。

我的原始代码如下,它根据传入的请求创建 XmlNode,并将结果附加到 XmlDocument 本身:

//p_transdoc is the XmlDocument that holds all the items to process.  
XmlNodeList nodelst_cnfrm = p_transdoc.SelectNodes("//OrderRequest");
foreach (XmlNode node in nodelst_cnfrm)
{
     //this is just an XML Object 
     XmlNode node_cnfrm_itm = this.CreateElement("ConfirmationItem");
     node_cnfrm_itm.Attributes.Append(this.CreateAttribute("name")).InnerText = p_transdoc.Attributes["name"].InnerText;

     XmlNode node_itmdtl = this.CreateElement("ItemDetail");
     node_cnfrm_itm.AppendChild(node_itmdtl);
//xml_doc is the return XML request                    
xml_doc.AppendChild(node_cnfrm_itm);
}

因此,在阅读了该线程和答案之后,我尝试更改代码以在每次传递时使用新的 XmlElement。

//p_transdoc is the XmlDocument that holds all the items to process.  
XmlNodeList nodelst_cnfrm = p_transdoc.SelectNodes("//OrderRequest");
foreach (XmlNode node in nodelst_cnfrm)
{
     XmlElement node_cnfrm_itm = new XmlElement();
     node_cnfrm_itm = this.CreateElement("ConfirmationItem");
     node_cnfrm_itm.Attributes.Append(this.CreateAttribute("name")).InnerText = p_transdoc.Attributes["name"].InnerText;

     XmlElement node_itmdtl = new XmlElement();
     node_itmdtl = this.CreateElement("ItemDetail");
     node_cnfrm_itm.AppendChild(node_itmdtl);
     //xml_doc is the return XML request                    
     xml_doc.AppendChild(node_cnfrm_itm);
}   

但这不仅不起作用,还会返回服务器错误。所以我来找你帮忙。现在这段代码只返回一个 ConfirmationItem。我如何才能将 ConfirmationItem 附加到文档的末尾而不是覆盖它,以便能够返回发送的数量?

(我应该指出,为了便于阅读、简单和减少困惑,这段代码已经过严格格式化。任何打印错误纯粹是因为 Asker 在有效校对方面的内部失败)。

最佳答案

假设 xml_doc 是带有 ConfirmationItems 的 xml,您需要用新的 XmlDocument 创建 XmlElements。 XmlDocument.CreateElement .因此我使用 Linq 扩展方法 OfType<>()这里只返回 XmlElement 类型的 XmlNode 对象。

// dummy data
XmlDocument p_transdoc = new XmlDocument();
p_transdoc.LoadXml(@"
<root name='rootAttribute'>
    <OrderRequest name='one' />
    <OrderRequest name='two' />
    <OrderRequest name='three' />
</root>
");

XmlDocument xml_doc = new XmlDocument();
xml_doc.LoadXml("<ReplyDocument />");

foreach (var node in p_transdoc.SelectNodes("//OrderRequest").OfType<XmlElement>())
{
    XmlElement node_cnfrm_itm = xml_doc.CreateElement("ConfirmationItem");
    node_cnfrm_itm = xml_doc.DocumentElement.AppendChild(node_cnfrm_itm) as XmlElement;
    node_cnfrm_itm.SetAttribute("name", node.GetAttribute("name"));

    XmlElement node_itmdtl = xml_doc.CreateElement("ItemDetail");
    node_itmdtl = node_cnfrm_itm.AppendChild(node_itmdtl) as XmlElement;
}

方法CreateElement返回一个 XmlElement,因此您可以使用方法 SetAttributeGetAttribute .

代码:p_transdoc.Attributes["name"].InnerText似乎不对。如果您想获取文档根元素的属性,您需要键入:p_transdoc.DocumentElement.GetAttribute("name")

IMO 如果您使用 Linq to XML,这会容易得多。

在 Linq to XML 中,这类似于(一些变量具有不同的名称):

 // dummy data
var transDoc = XDocument.Parse(@"
<root name='rootAttribute'>
    <OrderRequest name='one' />
    <OrderRequest name='two' />
    <OrderRequest name='three' />
</root>");

var xmlDoc = XDocument.Parse("<ReplyDocument />");

xmlDoc.Root.Add(
    transDoc.Root.Elements("OrderRequest").Select(o => 
        new XElement("ConfirmationElement",
            new XAttribute("name", (string)o.Attribute("name")),
            new XElement("ItemDetail"))));

两个示例输出:

<ReplyDocument>
  <ConfirmationElement name="one">
    <ItemDetail />
  </ConfirmationElement>
  <ConfirmationElement name="two">
    <ItemDetail />
  </ConfirmationElement>
  <ConfirmationElement name="three">
    <ItemDetail />
  </ConfirmationElement>
</ReplyDocument> 

关于c# - 将多个相似的 XML 节点附加到 XML 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5313002/

相关文章:

c# - 分块读取流失败 - 目标数组不够长

xml - XSLT 1不同分组

sql-server - 从 SQL Server 中的多表连接生成 XML

c# - .NET 中是否有 XmlDocument.LoadXml() 的 Java 等效项?

c# - 从大双值中获取字符串(C#)

c# - 如何在 Windows 窗体应用程序中实现控件验证?

c# - VB.NET 能否读取 XML?

c# - 将 C# 对象(包含静态对象成员)作为参数传递给 C++/CLI 程序

xml - Perl XML::DOM 在文件之间复制节点树

java - 外部 DRL 文件加载到多个 KieBase 实例中