我目前正在处理一个 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,因此您可以使用方法 SetAttribute
和 GetAttribute
.
代码: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/