Home > Back-end >  xdocument : moving elements to child node
xdocument : moving elements to child node

Time:05-26

I have below xml

<root>
    <row>
        <MARKET>stringText</MARKET>
        <START_DT>20210529</START_DT>
        <END_DT>20210529</END_DT>
        <TIME_ZONE>GMT</TIME_ZONE>
        <ACTION>INSERT</ACTION>
        <NODE1>1</NODE1>
        <NODE2>1.3</NODE2>
    </row>
    <row>
        <MARKET>stringText</MARKET>
        <START_DT>20210529</START_DT>
        <END_DT>20210529</END_DT>
        <TIME_ZONE>GMT</TIME_ZONE>
        <ACTION>INSERT</ACTION>
        <NODE1>1</NODE1>
        <NODE2>1.2</NODE2>
    </row>
</root>

I want to convert some of elements to new child node using c# xdocument. I'm new to this so and so far tried to search on how to move elements to child node but couldn't find anything.

<root>
    <row>
        <MARKET>stringText</MARKET>
        <START_DT>20210529</START_DT>
        <END_DT>20210529</END_DT>
        <TIME_ZONE>GMT</TIME_ZONE>
        <ACTION>INSERT</ACTION>
        <Sub_Node>
            <NODE1>1</NODE1>
            <NODE2>1.3</NODE2>
        </Sub_Node>
    </row>
    <row>
        <MARKET>stringText</MARKET>
        <START_DT>20210529</START_DT>
        <END_DT>20210529</END_DT>
        <TIME_ZONE>GMT</TIME_ZONE>
        <ACTION>INSERT</ACTION>
        <Sub_Node>
            <NODE1>1</NODE1>
            <NODE2>1.2</NODE2>
        </Sub_Node>
    </row>
</root>

CodePudding user response:

The solution

using System.Xml.Linq;

var source = "<root>\r\n    <row>\r\n        <MARKET>stringText</MARKET>\r\n        <START_DT>20210529</START_DT>\r\n        <END_DT>20210529</END_DT>\r\n        <TIME_ZONE>GMT</TIME_ZONE>\r\n        <ACTION>INSERT</ACTION>\r\n        <NODE1>1</NODE1>\r\n        <NODE2>1.3</NODE2>\r\n    </row>\r\n    <row>\r\n        <MARKET>stringText</MARKET>\r\n        <START_DT>20210529</START_DT>\r\n        <END_DT>20210529</END_DT>\r\n        <TIME_ZONE>GMT</TIME_ZONE>\r\n        <ACTION>INSERT</ACTION>\r\n        <NODE1>1</NODE1>\r\n        <NODE2>1.2</NODE2>\r\n    </row>\r\n</root>";
XDocument sourceXDoc;

using var stringReader = new StringReader(source);
sourceXDoc = XDocument.Load(stringReader);

foreach (var rowElement in sourceXDoc.Descendants().Where(_=>_.Name.LocalName == "row"))
{
    var node1 = rowElement.Element("NODE1");
    var node2 = rowElement.Element("NODE2");

    var subNode = new XElement("Sub_node");

    if (node1 != null)
    {
        subNode.Add(new XElement("SEGMENT_NUMBER", node1.Value));
        node1?.Remove();
    }

    if (node2 != null)
    {
        subNode.Add(new XElement("QUANTITY", node2.Value));
        node2?.Remove();
    }

    rowElement.Add(subNode);
}

Console.WriteLine(sourceXDoc.ToString());

Output

<root>
  <row>
    <MARKET>stringText</MARKET>
    <START_DT>20210529</START_DT>
    <END_DT>20210529</END_DT>
    <TIME_ZONE>GMT</TIME_ZONE>
    <ACTION>INSERT</ACTION>
    <Sub_node>
      <SEGMENT_NUMBER>1</SEGMENT_NUMBER>
      <QUANTITY>1.3</QUANTITY>
    </Sub_node>
  </row>
  <row>
    <MARKET>stringText</MARKET>
    <START_DT>20210529</START_DT>
    <END_DT>20210529</END_DT>
    <TIME_ZONE>GMT</TIME_ZONE>
    <ACTION>INSERT</ACTION>
    <Sub_node>
      <SEGMENT_NUMBER>1</SEGMENT_NUMBER>
      <QUANTITY>1.2</QUANTITY>
    </Sub_node>
  </row>
</root>

CodePudding user response:

I would suggest using the System.Xml.Linq namespace. Using these extensions, you can search your hierarchy to find the appropriate parent or sibling, and then use enter image description here

  • Related