将第一个子XML节点转换为其所有兄弟节点的父节点

时间:2014-01-14 16:13:03

标签: c# xml

我需要移动特定的第一个子节点并将其转换为父节点,如下所示:

我已经更改了XML以使其更清晰。

原始XML

<root version="1.0">
    <body>
        <nodeList projectName="testing charcharistics">
            <node modelDescription="I'm parent node which needs to be removed">
                <node modelCatalogNum="I'm First Son node to become parent node" attr1="1" attr2="2" ....... />
                <node modelCatalogNum="NETDIR-1" />
                <node modelCatalogNum="NETDIR-2" />
                <node modelCatalogNum="NETDIR-3" />
                .
                .
                .
                .
            </node>
        </nodeList>
    </body>
</root>

输出XML

<root version="1.0">
    <body>
        <nodeList projectName="testing charcharistics">
            <node modelCatalogNum="I'm First Son node to become parent node" attr1="1" attr2="2" ....... />
                <node modelCatalogNum="NETDIR-1" />
                <node modelCatalogNum="NETDIR-2" />
                <node modelCatalogNum="NETDIR-3" />
                .
                .
                .
                .
            </node>
        </nodeList>
    </body>
</root>

如您所见,第一个子节点已成为父节点。

我需要一个C#代码的通用解决方案,具体如下     步骤。

  1. 第一个儿子将成为其所有兄弟节点的父母
  2. 删除父节点。
  3. 有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

以下是您可以单独删除自闭标签的解决方案。

Test.xml - 您的原始xml和Test1.xml - 修改后的xml

        XmlDocument doc = new XmlDocument();
        doc.Load(@"E:\Test.xml");

        XmlNodeList elementList = doc.GetElementsByTagName("node");

        for (int i = 0; i < elementList.Count; i++)
        {
            if (elementList[0].Attributes["modelDescription"].Value == "My Model Description")
            {
                elementList[0].Attributes["modelDescription"].Value = elementList[1].Attributes["modelDescription"].Value;

                XmlAttribute newAttribute1 = doc.CreateAttribute("instanceName");
                newAttribute1.Value = elementList[1].Attributes["instanceName"].Value;
                elementList[0].Attributes.Append(newAttribute1);

                XmlAttribute newAttribute2 = doc.CreateAttribute("modelCatalogNum");
                newAttribute2.Value = elementList[1].Attributes["modelCatalogNum"].Value;
                elementList[0].Attributes.Append(newAttribute2);

                elementList[1].ParentNode.Attributes.Remove(elementList[0].Attributes["quantity"]);

                elementList[0].FirstChild.RemoveAll();
            }
        }

        doc.Save(@"E:\Test1.xml");  

答案 1 :(得分:1)

这种通用方法如何:

private static void Invert(XmlNode startingNode, string path)
{
    XmlNode node = startingNode.SelectSingleNode(path);
    if (node != null)
    {
        XmlNode firstChild = node.SelectSingleNode("*");

        if(firstChild != null)
        {
            XmlNodeList others = 
                 node.SelectNodes("node()[not(self::*)] | *[position() > 1]");
            foreach (XmlNode other in others)
            {
                firstChild.AppendChild(other);
            }
            node.ParentNode.ReplaceChild(firstChild, node);
        }
    }
}

您可以这样称呼它:

 Invert(doc, "/root/body/nodeList/node");

或者,您可以使用XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="nodeList/node">
    <xsl:apply-templates select="*[1]" mode="newParent" />
  </xsl:template>

  <xsl:template match="*" mode="newParent">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates select="../node()[generate-id() !=
                                             generate-id(current())]" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

答案 2 :(得分:0)

这个怎么样?

XmlDocument doc = new XmlDocument();
        doc.Load("Test.xml");

您可以发送变量来确定要删除的节点             XmlNodeList elementList = doc.GetElementsByTagName(“node”);

只是为了显示列表

        foreach (XmlNode node in elementList)
        {                
            Console.Write(node.Name + " ");
            foreach (XmlAttribute attr in node.Attributes)
            {
                Console.Write(attr.Name + ":" + attr.Value + " ");
            }
            Console.WriteLine();
        }

通用删除 - 基本上从父项中删除属性并添加第一个子项中的属性,删除子项

        var firstChild = elementList[0].FirstChild;
        elementList[0].Attributes.RemoveAll();
        for (int i = 0; i < firstChild.Attributes.Count; i++)
        {
            XmlAttribute item = doc.CreateAttribute(firstChild.Attributes[i].Name);
            item.Value = firstChild.Attributes[i].Value;
            elementList[0].Attributes.Append(item);
        }
        elementList[0].RemoveChild(firstChild);

只是为了显示列表

        Console.WriteLine();
        foreach (XmlNode node in elementList)
        {                
            Console.Write(node.Name + " ");
            foreach (XmlAttribute attr in node.Attributes)
            {
                Console.Write(attr.Name + ":" + attr.Value + " ");
            }
            Console.WriteLine();
        }

        Console.ReadLine();