0

我需要弄清楚如何使用 C# 将带有子节点的一条 XML 记录转换为多条记录。是的,我知道使用 XSLT 会更容易做到这一点,但这不是一个选择。我有一个必须修改以供 5 种不同用途使用的 XML 文件,所以我需要一个共同的起点。

请原谅我缺乏理解,但我找不到任何东西似乎朝着这个方向发展。一切都朝着另一个方向发展。这是我的代码和文件的示例。

源文件。

<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>
4

1 回答 1

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);
                                }
                            }
                        }
                    }
于 2013-07-15T17:52:17.257 回答