使用XSL转换XSL

时间:2012-05-17 09:10:40

标签: java xml xslt xalan

关于马丁答案的问题: Martin Honnen的答案很有效,但不是根本元素。假设我将“汽车”作为根元素:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="foo">
        <cars>
            <car1 />
            <car2 />
        </cars>
    </xsl:template>
</xsl:stylesheet>

我想获得:

<xsl:template match="foo">
    <cars>
        <car1 />
        <car2 />
        <TANK />
    </cars>
</xsl:template>

为此,我会使用:

<xsl:template match="cars" >
  <xsl:copy>
    <xsl:apply-templates/>
    <TANK />
  </xsl:copy>
</xsl:template> 

输出确切的输入,不做任何改动。我可以试试:

<xsl:template match="/" >
  <xsl:copy>
    <xsl:apply-templates/>
    <TANK />
  </xsl:copy>
</xsl:template> 

但它会将TANK节点放在样式表之外,如下所示:

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

<xsl:template match="order">
    <cars>
        <car1/>
        <car2/>
    </cars>
</xsl:template>
</xsl:stylesheet><TANK/>

如何在车内获得TANK元素?

原始问题: 我有一个用于转换XML的XSL:

XML_format1 -> XSL1 -> XML_format2

我需要转换第一个XSL文件(使用第二个XSL)来获取第三个XSL文件,该文件将输出第三种格式的XML。简而言之:

XSL1 -> XSL2 -> XSL3

XML_format1 -> XSL3 -> XML_format3

使用以下样式表,我可以复制第一个XSL的内容,也可以跳过某些节点:

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

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

<xsl:template match="//skipThisNode"/>

</xsl:stylesheet>

我的问题:除此之外,我还需要更改一些节点的结构(添加一些东西),从中:

<car>
    <color>green</color>
    <fuel>petrol</fuel>
</car>

对此:

<car>
    <color>green</color>
    <fuel>petrol</fuel>
    <topSpeed>99</topSpeed>
</car>

LE:我可以创建一个模板来匹配我需要添加子节点的特定节点,如下所示:

<xsl:template match="car">
    <color>
        <!-- existing value-of -->  
    </color>
    <fuel>
         <!-- existing value-of --> 
    </fuel>
    <topSpeed>
        <!-- * new value-of * -->  
    </topSpeed>
</xsl:template>

但这似乎超越了顶峰。是否有更简单的方法来实现我想要的目标?

1 个答案:

答案 0 :(得分:4)

我宁愿使用

<xsl:param name="newSpeed" select="99"/>

<xsl:template match="car">
  <xsl:copy>
    <xsl:apply-templates/>
    <topSpeed>
      <xsl:value-of select="$newSpeed"/>
    </topSpeed>
  </xsl:copy>
</xsl:template>

保持处理链,允许您在需要时添加模板以转换或删除car元素的子元素和后代。

[编辑] 我不确定我是否了解您的最新要求,因为输入似乎是一个完整的样式表,但随后作为您想要的输出,您只显示了一个模板。所以假设您输入为

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="order">
        <cars>
            <car1 />
            <car2 />
        </cars>
    </xsl:template>
</xsl:stylesheet>

你想要转换xsl:template的匹配属性以及我将使用的模板体中的文字结果元素

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

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

  <xsl:template match="xsl:template[@match = 'order']/@match">
    <xsl:attribute name="{name()}">
      <xsl:text>foo</xsl:text>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="xsl:template[@match = 'order']/cars">
    <xsl:copy>
      <xsl:apply-templates/>
      <TANK/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

我得到(用Saxon 6.5.5测试)结果

<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="foo">
        <cars>
            <car1/>
            <car2/>
        <TANK/></cars>
    </xsl:template>
</xsl:stylesheet>

希望你想要什么(或许缺少适当的缩进)。