while transforming attributes to element with XSLT

2019-09-09 06:27发布

问题:

I am using XSLT in order to transform certain xml that contains all values formated as attributes to another xml keeping the values as child element. In my xml there are two children name, one is aa and another is bbb. The transformation is working perfectly when I check the values for both aa and bbb. The problem is I want to delete/ignore the attributes found in the parent element of these children element.

I am showing below the must two significant tentatives I have tried so far. The first one is my original idea but I want it avoiding the parent attributes (exactly "cod" and"package" in my xml).

The second is the consequence of searching around but it is actually driving away from what I want. Nevertheless, the second tentative can help me express that I am probably missing either certain "pattern" or some "comand" to skip the attributes from root element.

MyApp.java

Path f = Paths.get("C:\\in1.xsl");
//Path f = Paths.get("C:\\in2.xsl");
InputStream resourceAsStream = Files.newInputStream(f);
StreamSource xsl = new StreamSource(resourceAsStream);
Transformer transformer;
transformer = TransformerFactory.newInstance().newTransformer(xsl);
StreamSource in = new StreamSource(
              new FileInputStream("C:\\my_xml.xml"));
StreamResult out = new StreamResult(System.out);
transformer.transform(in, out); //in1 produced out1 and in2 produced out2

my_xml.xml

<c:product xmlns:c="myapp">
       <c:item cod="789">
              <c:aa name="024" value="123"/>
              <c:bbb name="0105" value="123456"/>
              <c:bbb name="0122" value="T"/>
              <c:aa name="071" value="00000001"/>
       </c:item>
       <c:item package="123" cod="11111">
              <c:aa name="002" value="753"/>
              <c:aa name="003" value="456"/>
              <c:bbb name="0146" value="147852"/>
       </c:item>
</c:product>

in1.xsl

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" encoding="UTF-8" indent="yes" standalone="no" omit-xml-declaration="yes"/>
       <xsl:template match="@*">
              <xsl:element name="{name(.)}">
                     <xsl:value-of select="."/>
              </xsl:element>
       </xsl:template>
       <xsl:template match="*">
              <xsl:copy>
                     <xsl:apply-templates select="@*|node()"/>
              </xsl:copy>
       </xsl:template>
</xsl:stylesheet>

in2.xls (source Copy XML file contents except for root node and attribute XSLT)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


  <xsl:output method="xml" omit-xml-declaration="yes" encoding="utf-8"/>
  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>
  <xsl:template match="/*">
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>

out1.xml (I don’t want cod element in first item neither I want package and cod in second item)

<c:product xmlns:c="myapp">
<c:item>
<cod>789</cod>
<c:aa>
<name>024</name>
<value>123</value>
</c:aa>
<c:bbb>

<name>0105</name>

<value>123456</value>

</c:bbb>

<c:bbb>

<name>0122</name>

<value>T</value>

</c:bbb>

<c:aa>

<name>071</name>

<value>00000001</value>

</c:aa>

</c:item>

<c:item>

<package>123</package>

<cod>11111</cod>

<c:aa>

<name>002</name>

<value>753</value>

</c:aa>

<c:aa>

<name>003</name>

<value>456</value>

</c:aa>

<c:bbb>

<name>0146</name>

<value>147852</value>

</c:bbb>

</c:item>

</c:product>

out2.xml (well, there is a single point here that I tried to take advantage to express my self: the root element receives a different treatment. If I find how to treat the root element by ignoring their attributes and mixed with the rest of in.xls I will probably discover my solution)

      <aa name="024" value="123"/>

      <bbb name="0105" value="123456"/>

      <bbb name="0122" value="T"/>

      <aa name="071" value="00000001"/>

      <aa name="002" value="753"/>

      <aa name="003" value="456"/>

      <bbb name="0146" value="147852"/>

回答1:

I am guessing (!) you want to do something like:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:c="myapp"
exclude-result-prefixes="c">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="c:item">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

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

</xsl:stylesheet>

When applied to your input example, the result will be:

<product>
   <item>
      <aa>
         <name>024</name>
         <value>123</value>
      </aa>
      <bbb>
         <name>0105</name>
         <value>123456</value>
      </bbb>
      <bbb>
         <name>0122</name>
         <value>T</value>
      </bbb>
      <aa>
         <name>071</name>
         <value>00000001</value>
      </aa>
   </item>
   <item>
      <aa>
         <name>002</name>
         <value>753</value>
      </aa>
      <aa>
         <name>003</name>
         <value>456</value>
      </aa>
      <bbb>
         <name>0146</name>
         <value>147852</value>
      </bbb>
   </item>
</product>

Note that the c:item element getting special treatment (2nd template) is not the root element.



标签: xml xslt dom