Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert inline XML node to nested nodes in asp.net using c#

Tags:

c#

xml

asp.net

I've an XML file such as below:

<?xml version="1.0" encoding="utf-8" ?>
<LayoutControl ID="rootlyt" Type="LayoutControl">
  <LayoutGroup ID="lgp8" Header="PersonalInfo" IsCollapsed="False" IsLocked="False" Orientation="Vertical" View="GroupBox" HorizontalAlignment="Left" VerticalAlignment="Top" Width="380" Height="295" Type="GroupItem" Properties="IsCollapsible=False,IsCollapsed=False,IsLocked=False,">
    <Element ID="layout2" HorizontalAlignment="Left" VerticalAlignment="Top" Width="300" Height="25" Label="Name" Background="#00FFFFFF" ContentName="txt2" Type="TextEdit" />
  </LayoutGroup>
</LayoutControl>  

For some reasons , I need to create child and nested nodes from the Element node attributes.
The output that I want is:

<?xml version="1.0" encoding="utf-8" ?>
<LayoutControl ID="rootlyt" Type="LayoutControl">
  <LayoutGroup ID="lgp8" Header="PersonalInfo" IsCollapsed="False" IsLocked="False" Orientation="Vertical" View="GroupBox" HorizontalAlignment="Left" VerticalAlignment="Top" Width="380" Height="295" Type="GroupItem" Properties="IsCollapsible=False,IsCollapsed=False,IsLocked=False,">
    <Element >
      <ID>layout2</ID>
      <HorizontalAlignment>Left</HorizontalAlignment>
      <VerticalAlignment>Top</VerticalAlignment>
      <Width>300</Width>
      <Height>25</Height>
      <Label>Name</Label>
      <Background>#00FFFFFF</Background>
      <ContentName>txt2</ContentName>
      <Type>TextEdit</Type>
    </Element>
  </LayoutGroup>
</LayoutControl>  

How can i do it?
Or any idea , reference ,article ...

Thanks.

like image 287
Hamid Talebi Avatar asked Apr 23 '16 07:04

Hamid Talebi


2 Answers

This is one possible way; for each <Element>'s attribute add a corresponding child element, and then remove all the attributes afterwards :

var raw = @"<LayoutControl ID='rootlyt' Type='LayoutControl'>
  <LayoutGroup ID='lgp8' Header='PersonalInfo' IsCollapsed='False' IsLocked='False' Orientation='Vertical' View='GroupBox' HorizontalAlignment='Left' VerticalAlignment='Top' Width='380' Height='295' Type='GroupItem' Properties='IsCollapsible=False,IsCollapsed=False,IsLocked=False,'>
    <Element ID='layout2' HorizontalAlignment='Left' VerticalAlignment='Top' Width='300' Height='25' Label='Name' Background='#00FFFFFF' ContentName='txt2' Type='TextEdit' />
  </LayoutGroup>
</LayoutControl>";

var doc = XDocument.Parse(raw);
foreach(var element in doc.Descendants("Element"))
{
    //add a series of child elements according to existing attributes
    element.Add(
        element.Attributes()
               .Select(attribute => new XElement(attribute.Name.LocalName, attribute.Value))
    );

    //remove the attributes
    element.Attributes().Remove();
}

Console.WriteLine(doc.ToString());

dotnetfiddle demo

For more complex transformations of XML, look into XSLT.

like image 170
har07 Avatar answered Sep 30 '22 09:09

har07


Here is an XSL Style Sheet Coded for your exact file. Hopefully this is what you need.

You can use an online XSL Transfrom tool like this one or use a script.

Here is the XSL:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<LayoutControl ID="rootlyt" Type="LayoutControl">
    <LayoutGroup ID="lgp8" Header="PersonalInfo" IsCollapsed="False" IsLocked="False" Orientation="Vertical" View="GroupBox" HorizontalAlignment="Left" VerticalAlignment="Top" Width="380" Height="295" Type="GroupItem" Properties="IsCollapsible=False,IsCollapsed=False,IsLocked=False,">
      <xsl:for-each select="/LayoutControl/LayoutGroup/Element">
        <Element>
            <ID><xsl:value-of select="@ID"/></ID>
            <HorizontalAlignment><xsl:value-of select="@HorizontalAlignment"/></HorizontalAlignment>
            <VerticalAlignment><xsl:value-of select="@VerticalAlignment"/></VerticalAlignment>
            <Width><xsl:value-of select="@Width"/></Width>
            <Height><xsl:value-of select="@Height"/></Height>
            <Label><xsl:value-of select="@Label"/></Label>
            <Background><xsl:value-of select="@Background"/></Background>
            <ContentName><xsl:value-of select="@ContentName"/></ContentName>
            <Type><xsl:value-of select="@Type"/></Type>
        </Element>
      </xsl:for-each>
    </LayoutGroup>
</LayoutControl>
</xsl:template>

</xsl:stylesheet>
like image 23
ib11 Avatar answered Sep 30 '22 11:09

ib11