hkwarrior
hkwarrior

Reputation: 35

Transform XML format to another XML format using XSLT (add one line in the output xml)

I am new to XSLT and xml, I need to change the input xml to the output xml, assumes practically nothing is known in advance about the input and output XML.

Input

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ad:AcceptDataInfo xmlns:ad="http://www.abc.com">
<ad:Product>ABC</ad:Product>
<ad:Filename>test.pdf</ad:Filename>
<ad:AccountNo>123</ad:AccountNo>
<ad:Date>20140429</ad:Date>
<ad:Time>160102</ad:Time>
</ad:AcceptDataInfo>

output expected

<Documents>
<Document>
<Prop>
  <Name>Product</Name>
  <Value>ABC</Value>
</Prop>
<Prop>
  <Name>Filename</Name>
  <Value>test.pdf</Value>
</Prop>
<Prop>
  <Name>AccountNo</Name>
  <Value>123</Value>
</Prop>
<Prop>
  <Name>Date</Name>
  <Value>20140429</Value>
</Prop>
<Prop>
  <Name>Time</Name>
  <Value>160102</Value>
</Prop>
<File>test.pdf</File>
</Document>
</Documents>

xslt file

<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="/*">
    <Documents>
        <Document>
            <xsl:apply-templates select="*"/>
        </Document>
    </Documents>
</xsl:template>

<xsl:template match="*">
    <Prop>
      <Name><xsl:value-of select="local-name()"/></Name>
      <Value><xsl:value-of select="."/></Value>
    </Prop>
</xsl:template>

<xsl:template match=
  "Value[count(.|((//Value)[2])) = 1]">
    <File>
      <xsl:apply-templates />
    </File>
</xsl:template>  

</xsl:stylesheet>

the problem is, the output does not include the following line test.pdf the value of the file tag is copied from filename tag

Any help will be appreciated, thank you.

Upvotes: 1

Views: 370

Answers (1)

Joel M. Lamsen
Joel M. Lamsen

Reputation: 7173

Well, the problem with your stylesheet is that you are matching Value, which is not in the input XML.

You could try the following stylesheet:

<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="/*">
        <Documents>
            <Document>
                <xsl:apply-templates select="*"/>
                <File><xsl:value-of select="child::*[local-name() = 'Filename']"/></File>
            </Document>
        </Documents>
    </xsl:template>

    <xsl:template match="*">
        <Prop>
            <Name><xsl:value-of select="local-name()"/></Name>
            <Value><xsl:value-of select="."/></Value>
        </Prop>
    </xsl:template>

</xsl:stylesheet>

Upvotes: 1

Related Questions