![](/img/trans.png)
[英]append multiple datasets with a foreach loop in an xml document
[英]Append Multiple Similar XML Nodes to XML Document
我目前正在處理XML請求,並且我正在嘗試創建一個在調用中具有多個同名子節點的Reply Document,所以我想要返回的是:
<Reply Document>
<ConfirmationItem name = "One">
<ItemDetail />
</ConfirmationItem>
<ConfirmationItem name = "Two">
<ItemDetail />
</ConfirmationItem>
...
<ConfirmationItem name = "Twenty">
<ItemDetail />
</ConfirmationItem>
</Reply Document>
我做了一些研究並找到了這個帖子: XmlReader AppendChild沒有附加相同的子值 ,其中接受的答案是OP必須創建新元素才能追加到末尾而不是覆蓋第一個。
我的原始代碼如下,它從傳入的Request創建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附加到Document的末尾而不是覆蓋它,以便能夠返回盡可能多的數量?
(我應該指出,這段代碼經過大量格式化,易於閱讀,簡單,並且可以減少混亂。任何印刷錯誤都純粹是因為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")
如果您使用Linq to XML,IMO會更容易。
在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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.