Home > Software design >  Transform XSLT attributes to elements
Transform XSLT attributes to elements

Time:10-07

I am trying to transform my XML. I have been able to get it partly working, but i can not get it right

I have included what i have been able to get to work, and what i am trying to get the final output to look like. Any help would be great. I have checked multiple searches and have only got it to work kinda of.

Current Output:

 <?xml version="1.0" encoding="utf-8"?>
<objects>
  <object><class>fhwed8885_notices</class><name>notices</name>
    <property><name>DocumentInformation</name>
      <object><class>fhwed8885_DocumentInformation</class><name>DocumentInformation</name>
        <property><name>DocId</name><value>510047</value></property>
        <property><name>GenerationType</name><value>pdf</value></property>
        <property><name>ReqId</name><value>aaa12345-555435d-ggaade5</value></property>
        <property><name>FilePath</name><value>missing</value></property>
      </object>
    </property>
    <property><name>PNAME</name>
      <object><class>fhwed8885_PNAME</class><name>PNAME</name>
        <property><name>NAME</name><value>JOHN KINGHT</value></property>
        <property><name>ADDR01</name><value>1896 KELLER SPRINGS</value></property>
        <property><name>ADDR02</name><value></value></property>
        <property><name>ADDR03</name><value></value></property>
        <property><name>ADDR04</name><value>ADDISON, TX 75181-0000</value></property>
      </object>
    </property>
  </object>
</objects>

XML Input:

<objects>
    <object  name="notices">
        <property name="DocumentInformation">
            <object  name="DocumentInformation">
                <property name="DocId" value="510047"/>
                <property name="GenerationType" value="pdf"/>
                <property name="ReqId" value="aaa12345-555435d-ggaade5"/>
                <property name="FilePath" value="missing"/>
            </object>
        </property>
        <property name="PNAME">
            <object  name="PNAME">
                <property name="NAME" value="JOHN KINGHT"/>
                <property name="ADDR01" value="1896 KELLER SPRINGS"/>
                <property name="ADDR02" value=""/>
                <property name="ADDR03" value=""/>
                <property name="ADDR04" value="ADDISON, TX 75181-0000"/>
            </object>
        </property>
    </object>
</objects>

XSLT Transform:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:apply-templates select="node()"/>
        <xsl:element name="{name()}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Looking for

<?xml version="1.0" encoding="utf-8"?>
<notices>
    <DocumentInformation>
        <DocId>510047</DocId>
        <GenerationType>pdf</GenerationType>
        <ReqId>aaa12345-555435d-ggaade5</ReqId>
        <ReqFilePath>missing</ReqFilePath>
    </DocumentInformation>
    <PNAME>
        <NAME>JOHN KINGHT</NAME>
        <ADDR01>1896 KELLER SPRINGS</ADDR01>
        <ADDR02/>
        <ADDR03/>
        <ADDR04>ADDISON, TX 75181-0000</ADDR04>
    </PNAME>
</notices>

CodePudding user response:

Try something like:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*[@name]">
    <xsl:element name="{@name}">
        <xsl:value-of select="@value" />
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

The result is not exactly identical to the one you show - but I don't know which one of the double headings should be removed.

Note also that this assumes that the root objects element has only one object child. Otherwise the result will be an XML fragment, not a well-formed XML document.

CodePudding user response:

This should do it:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:strip-space elements="*"/>


  <xsl:template match="*[@name]">
    <xsl:element name="{@name}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>
    
  <!-- Skip elements that have a child that has the same value for @name-->
  <xsl:template match="*[@name=child::*/@name]" priority="2">
    <xsl:apply-templates select="*"/>
  </xsl:template>

  <xsl:template match="@name|@class"/>

</xsl:stylesheet>
  • Related