如何在没有XSLT或SQL的情况下,将一个带有子节点的XML记录转换为多个记录

本文关键字:记录 一个 XML 转换 子节点 XSLT SQL 情况下 | 更新日期: 2023-09-27 18:21:39

我需要弄清楚如何使用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>

如何在没有XSLT或SQL的情况下,将一个带有子节点的XML记录转换为多个记录

我想明白了。通过将每个节点封装在一个行节点循环中,我得到了我想要的结果。

                   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);
                                }
                            }
                        }
                    }
相关文章: