سؤال

I am new to XSLT, I need to change the input xml to the output xml

Input

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ad:AcceptDataInfo xmlns:ad="http://www.abc.com">
<ad:Product>ABC</ad:SubType>
<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>AccountNo</Name>
  <Value>123</Value>
</Prop>
<Prop>
  <Name>Date</Name>
  <Value>20140429</Value>
</Prop>
<Prop>
  <Name>Time</Name>
  <Value>160102</Value>
</Prop>
</Document>
</Documents>

my xslt (not complete)

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

  <xsl:template match="*">
    <xsl:element name="{local-name(.)}">
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@*">
    <xsl:attribute name="{local-name(.)}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

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

</xsl:stylesheet>

I've searched through the web, can only remove namespace prefix, and add some of the tags, thanks in advance!

هل كانت مفيدة؟

المحلول

It is difficult to determine the logic of the transformation based on a single example. I am guessing you want something like this:

<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:stylesheet>

When the above is applied to the (corrected!) input of:

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

the following result is produced:

<?xml version="1.0" encoding="UTF-8"?>
<Documents>
   <Document>
      <Prop>
         <Name>Product</Name>
         <Value>ABC</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>
   </Document>
</Documents>

Note that this assumes practically nothing is known in advance about the source XML except that it has a two-level structure (root element and children of root element). Otherwise we could make the transformation less generic and as a result, more efficient.

نصائح أخرى

There are a number of issues here:

  • your stylesheet doesn't declare <Prop>, <Name> or <Value> elements anywhere;
  • the only place you use value-of is in an attribute-matching template - to get any of the element values you'll need to do this inside an element-matching template or select nodes in the form select='element_name/text()'

It would be helpful if you annotated each element in your stylesheet with what you expected it to do, in order to work out where your understanding is flawed. XSLT questions often boil down to 'what were you expecting?' and this usually isn't obvious from reading a (faulty) stylesheet.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top