如何在任意路径下用xslt输出



我在xslt中有以下问题。给定示例xml:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <cd>A</cd>
  <dvd id='A'>B</dvd>
  <dvd id='B'>C</dvd>
</catalog>

我想输出标签cdCD, dvd[@id="B"]CD,所有其他dvdDVD。使用三个模板(cd、dvd和dvd, id=B)的简单转换工作得很好,但是产生的结果如下:

<CD>A</CD>
<DVD>B</DVD>
<CD>C</CD>

问题是验证模式期望DVD s遵循CD s,因此CD->DVD->CD是错误的。我想出了这个模式来解决这个问题:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="catalog">
    <xsl:apply-templates/>  
  </xsl:template>
  <xsl:template match="cd">
    <CD>
      <xsl:value-of select="."/>
    </CD>
    <xsl:if test="../dvd[@id='B']">
      <xsl:apply-templates select="../dvd[@id='B']" mode="keep"/>
    </xsl:if>
  </xsl:template>
  <xsl:template match="dvd">
    <DVD>
      <xsl:value-of select="."/>
    </DVD>
  </xsl:template>
  <xsl:template match="dvd[@id='B']" mode="keep">
    <CD>
      <xsl:value-of select="."/>
    </CD>
  </xsl:template>
  <xsl:template match="dvd[@id='B']">
    <!-- do nothing -->
  </xsl:template>
</xsl:stylesheet>

它完成了工作,但似乎有点冗长和复杂——我正在检查一个节点是否存在,转换它,当它出现在正常的处理流中时,我忽略它——我甚至不确定它是否完全正确。

你能建议一种方法,其中dvd[@id="B"]将只有一个模板,将<CD>输出在路径下,如"在此级别的最后一张cd之后"?

如何:

XSLT 1.0

<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:template match="catalog">
    <xsl:apply-templates select="cd | dvd[@id='B']"/>  
    <xsl:apply-templates select="dvd[not(@id='B')]"/>  
</xsl:template>
<xsl:template match="cd">
    <CD>
        <xsl:value-of select="."/>
    </CD>
</xsl:template>
<xsl:template match="dvd">
    <DVD>
        <xsl:value-of select="."/>
    </DVD>
</xsl:template>
<xsl:template match="dvd[@id='B']">
    <CD>
        <xsl:value-of select="."/>
    </CD>
</xsl:template>
</xsl:stylesheet>

或者,如果你愿意:

XSLT 1.0

<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:template match="catalog">
    <xsl:apply-templates select="cd | dvd[@id='B']"/>  
    <xsl:apply-templates select="dvd[not(@id='B')]"/>  
</xsl:template>
<xsl:template match="cd | dvd[@id='B']">
    <CD>
        <xsl:value-of select="."/>
    </CD>
</xsl:template>
<xsl:template match="dvd">
    <DVD>
        <xsl:value-of select="."/>
    </DVD>
</xsl:template>
</xsl:stylesheet>

注意,结果不是格式良好的XML,因为它没有单个根元素。

相关内容

  • 没有找到相关文章

最新更新