我需要弄清楚如何使用C#将一个带有子节点的XML记录转换成多个记录。是的,我知道使用XSLT更容易做到这一点,但这不是一个选择。我有一个XML文件,必须修改为5种不同的用途,所以我需要一个共同的起点。
原谅我缺乏理解,但我找不到的东西似乎朝这个方向发展。一切都朝着另一个方向发展。这是我的代码和文件的示例。
源文件。
<inventoryitems>
<inventoryitem>
<id>11101</id>
<displayname>LG HAMBURGER PATTY</displayname>
<basemeasure>EACH</basemeasure>
<reportingmeasure>EACH</reportingmeasure>
<measures>
<measure>
<name>CS</name>
<factor>1.000000</factor>
<isactive>1</isactive>
</measure>
<measure>
<name>ST</name>
<factor>8.000000</factor>
<isactive>1</isactive>
</measure>
<measure>
<name>EACH</name>
<factor>120.000000</factor>
<isactive>1</isactive>
</measure>
</measures>
<categories>
<category>
<name>MEATS</name>
</category>
</categories>
<locations />
<skus />
</inventoryitem>
<inventoryitem>
<id>11102</id>
<displayname>SM HAMBURGER PATTY</displayname>
<basemeasure>EACH</basemeasure>
<reportingmeasure>EACH</reportingmeasure>
<measures>
<measure>
<name>ST</name>
<factor>6.000000</factor>
<isactive>1</isactive>
</measure>
<measure>
<name>CS</name>
<factor>1.000000</factor>
<isactive>1</isactive>
</measure>
<measure>
<name>EACH</name>
<factor>96.000000</factor>
<isactive>1</isactive>
</measure>
</measures>
<categories>
<category>
<name>MEATS</name>
</category>
</categories>
<locations />
<skus />
</inventoryitem>
<inventoryitem>
<id>11202</id>
<displayname>BREAD SM BUN 4</displayname>
<basemeasure>EACH</basemeasure>
<reportingmeasure>EACH</reportingmeasure>
<measures>
<measure>
<name>TR</name>
<factor>1.000000</factor>
<isactive>1</isactive>
</measure>
<measure>
<name>EACH</name>
<factor>30.000000</factor>
<isactive>1</isactive>
</measure>
</measures>
<categories>
<category>
<name>BAKERY</name>
</category>
</categories>
<locations />
<skus />
</inventoryitem>
</inventoryitems>
我需要得到的东西会是这样的。
<data>
<row InventoryItemId="11201" ItemDescription="BREAD LG BUN 5" CategoryName="BAKERY" Measure="TR" />
<row InventoryItemId="11201" ItemDescription="BREAD LG BUN 5" CategoryName="BAKERY" Measure="EACH" />
</data>
当只有一个节点时,我能够编写代码来将值模式化为属性,但是当存在具有多个值的子节点时,我无法做什么。
invlist = results.Substring(results.IndexOf("<inventoryitems>"), (results.IndexOf("</inventoryitemsresponsedata>") - results.IndexOf("<inventoryitems>")));
XmlDocument doc = new XmlDocument();
XmlNode nd = doc.CreateNode("element", "data", "");
doc.AppendChild(nd);
//XmlNode rw = doc.CreateNode("element", "row", "");
//nd.AppendChild(rw);
var invitems = new XmlDocument { InnerXml = invlist };
XmlNode result = doc.ImportNode(invitems.DocumentElement, true);
nd.AppendChild(result);
XmlNodeList ndList = doc.SelectNodes("data/inventoryitems/inventoryitem");
foreach (XmlNode id in ndList)
{
XmlNode idnode = id.SelectSingleNode("id");
if (idnode != null)
{
XmlNode rw = doc.CreateNode("element", "row", "");
nd.AppendChild(rw);
var attribute = doc.CreateAttribute("InventoryItemId");
attribute.Value = idnode.InnerXml;
var Description = doc.CreateAttribute("ItemDescription");
Description.Value = id.SelectSingleNode("displayname").InnerXml;
rw.Attributes.Append(attribute);
rw.Attributes.Append(Description);
}
XmlNodeList msList = id.SelectNodes("measures/measure");
foreach (XmlNode mes in msList)
{
XmlNode msnode = mes.SelectSingleNode("name");
if (msnode != null)
{
var attribute = doc.CreateAttribute("Measure");
attribute.Value = msnode.InnerXml;
//rw.Attributes.Append(attribute);
mes.Attributes.Append(attribute);
}
}
}
任何帮助将不胜感激。
更新:这就是我得到的。
<data>
<row InventoryItemId="11201" ItemDescription="BREAD LG BUN 5" CategoryName="BAKERY" />
<inventoryitem>
<measures>
<measure Measure="TR"></measure>
<measure Measure="EACH"></measure>
</measures>
<locations />
<skus />
</inventoryitem>
</data>
答案 0 :(得分:0)
我明白了。通过将每个节点包装在行节点循环中,我得到了我正在寻找的结果。
var item = idnode.InnerXml;
XmlNodeList rwList = doc.SelectNodes(String.Format("data/row[@InventoryItemId='{0}']",item));
var rwCount = rwList.Count;
foreach (XmlNode rw in rwList)
{
XmlNodeList msList = id.SelectNodes("measures/measure");
foreach (XmlNode mes in msList)
{
XmlNode msnode = mes.SelectSingleNode("name");
{
var attribute = doc.CreateAttribute("Measure");
attribute.Value = msnode.InnerXml;
if (rwCount > 0)
{
rw.Attributes.Append(attribute);
rwCount--;
}
else
{
XmlNode clonenode = rw.Clone();
clonenode.Attributes.Append(attribute);
nd.AppendChild(clonenode);
}
}
}
}