使用XSL将一种XML格式转换为另一种XML格式

时间:2011-04-29 10:40:08

标签: xml xslt spring-mvc

我有一个XML输出的代码

<?xml version="1.0" encoding="windows-1252" standalone="yes"?>
<products>
    <product>
        <name>abc</name>
        <id>1</id>
    </product>
    <product>
        <name>klm</name>
        <id>2</id>
    </product>
</products>

我希望以下列格式显示相同的XML:

<?xml version="1.0" encoding="windows-1252" standalone="yes"?>
<products>
    <product>
        <name>
            <value>abc</value>
            <unit></unit>
        </name>
        <id>
            <value>1</value>
            <unit></unit>
        </id>
        <product>
        <name>
            <value>klm</value>
            <unit></unit>
        </name>
        <id>
            <value>2</value>
            <unit></unit>
        </id>
</product>

如何使用XSLT进行操作?

我正在使用Spring环境。产品的XML标签是可变的。这些因产品种类而异。生成XML的代码是

JAXBContext jc;
try {
   jc = JAXBContext.newInstance(cla);
   Marshaller m;
   m = jc.createMarshaller();
   m.marshal(obj, out); 
} catch (JAXBException e) {
   e.printStackTrace();
}

编辑: 产品可能有重量,因此也会有

标签
<weight>10lbs<weight>

这个标准将闯入

<weight>
    <value>10</value>
    <unit>lbs</unit>
</weight> 

2 个答案:

答案 0 :(得分:0)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="/products">
  <xsl:for-each select="product">
   <xsl:element name="product">
     <xsl:element name="name">
       <xsl:element name="value"><xsl:value-of select="name"/></xsl:element>
       <xsl:element name="unit"/>
     </xsl:element>
     <xsl:element name="id">
       <xsl:element name="value"><xsl:value-of select="id"/></xsl:element>
       <xsl:element name="unit"/>
      </xsl:element>
   </xsl:element>
  </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

以下是一个示例样式表[已编辑以反映权重元素的新要求]:

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

 <xsl:strip-space elements="*"/>
 <xsl:output indent="yes"/>

 <xsl:template match="products">
   <xsl:copy>
     <product>
       <xsl:apply-templates select="product/*"/>
     </product>
   </xsl:copy>
 </xsl:template>

 <xsl:template match="product/*">
   <xsl:copy>
     <value>
       <xsl:value-of select="."/>
     </value>
     <unit></unit>
   </xsl:copy>
 </xsl:template>

 <xsl:template match="product/weight" priority="3">
   <xsl:copy>
     <value>
       <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
     </value>
     <unit>
       <xsl:value-of select="translate(., '0123456789', '')"/>
     </unit>
   </xsl:copy>
 </xsl:template>

</xsl:stylesheet>

当我将其应用于样本输入

<products>
    <product>
        <name>abc</name>
        <id>1</id>
    </product>
    <product>
        <name>klm</name>
        <id>2</id>
    </product>
    <product>
        <name>foo</name>
        <id>3</id>
        <weight>10lbs</weight>
     </product>
</products>

我得到了

<products>
   <product>
      <name>
         <value>abc</value>
         <unit/>
      </name>
      <id>
         <value>1</value>
         <unit/>
      </id>
      <name>
         <value>klm</value>
         <unit/>
      </name>
      <id>
         <value>2</value>
         <unit/>
      </id>
      <name>
         <value>foo</value>
         <unit/>
      </name>
      <id>
         <value>3</value>
         <unit/>
      </id>
      <weight>
         <value>10</value>
         <unit>lbs</unit>
      </weight>
   </product>
</products>

基于亚历杭德罗的评论,我可能误读了想要的输出,你不想合并产品,在这种情况下使用

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

 <xsl:strip-space elements="*"/>
 <xsl:output indent="yes"/>

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

 <xsl:template match="product/*">
   <xsl:copy>
     <value>
       <xsl:value-of select="."/>
     </value>
     <unit></unit>
   </xsl:copy>
 </xsl:template>

 <xsl:template match="product/weight" priority="3">
   <xsl:copy>
     <value>
       <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
     </value>
     <unit>
       <xsl:value-of select="translate(., '0123456789', '')"/>
     </unit>
   </xsl:copy>
 </xsl:template>

</xsl:stylesheet>

然后你得到

<products>
   <product>
      <name>
         <value>abc</value>
         <unit/>
      </name>
      <id>
         <value>1</value>
         <unit/>
      </id>
   </product>
   <product>
      <name>
         <value>klm</value>
         <unit/>
      </name>
      <id>
         <value>2</value>
         <unit/>
      </id>
   </product>
   <product>
      <name>
         <value>foo</value>
         <unit/>
      </name>
      <id>
         <value>3</value>
         <unit/>
      </id>
      <weight>
         <value>10</value>
         <unit>lbs</unit>
      </weight>
   </product>
</products>