XSLT 1.0输出逗号分隔列表时处理空元素

时间:2012-09-01 18:18:18

标签: xslt comma separator

我是stackoverflow的新手,非常感谢任何帮助。 这是我遇到的XSLT 1.0问题,我确信有一个简单的解决方案,我找不到它。

我有顶级book元素,其中包含许多章节,每个章节都有一个标题:

<?xml version="1.0" encoding="utf-8"?>
<Book>
  <Chapter>
    <Title>ONE</Title>
  </Chapter>
  <Chapter>
    <Title>TWO</Title>
  </Chapter>
  <Chapter>
    <Title></Title>
  </Chapter>
  <Chapter>
    <Title>FOUR</Title>
  </Chapter>
</Book>

我想将上面的内容转换为一个名为CSV-Title-List的元素。直到出现空标题的情况似乎很容易。我使用以下样式表获得了一个意外的逗号:

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

    <xsl:template match="Book">
      <CSV-Title-List>
      <xsl:for-each select="Chapter/Title">
        <xsl:value-of select="."/>
        <xsl:if test="position() &lt; last()">
          <xsl:text>, </xsl:text>
        </xsl:if>
      </xsl:for-each>
      </CSV-Title-List>
    </xsl:template>   
</xsl:stylesheet>

我的问题是,在使用上面的样式表输出逗号之前,如何干净地检查下一个章节/标题的空字符串。肯定有更好的办法?任何建议,将不胜感激。感谢任何建议。

2 个答案:

答案 0 :(得分:1)

此转化:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="Chapter[normalize-space(Title)]"/>
 </xsl:template>

 <xsl:template match="Chapter">
  <xsl:if test="not(position()=1)">,</xsl:if>
  <xsl:value-of select="Title"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<Book>
  <Chapter>
    <Title>ONE</Title>
  </Chapter>
  <Chapter>
    <Title>TWO</Title>
  </Chapter>
  <Chapter>
    <Title></Title>
  </Chapter>
  <Chapter>
    <Title>FOUR</Title>
  </Chapter>
</Book>

会产生想要的正确结果:

ONE,TWO,FOUR

对不同的XML文档应用相同的转换时 - 其中第一个/*/Chapter/Title只有一个空白字符串值

<Book>
  <Chapter>
    <Title>     </Title>
  </Chapter>
  <Chapter>
    <Title>TWO</Title>
  </Chapter>
  <Chapter>
    <Title></Title>
  </Chapter>
  <Chapter>
    <Title>FOUR</Title>
  </Chapter>
</Book>

再次产生正确的,想要的结果

TWO,FOUR

答案 1 :(得分:0)

即使您的第一个Title元素为空白,也可以使用此解决方案。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:strip-space elements="*" />

 <xsl:template match="Book">
  <xsl:variable name="booklist">
   <xsl:apply-templates />
  </xsl:variable>
  <xsl:value-of select="substring($booklist,2)" />
 </xsl:template>

 <xsl:template match="Title/text()">
  <xsl:text>,</xsl:text>
  <xsl:copy />
 </xsl:template>
</xsl:stylesheet>

它也不使用显式条件,只是在每个值前加一个逗号,将结果存储在变量中,然后从第二个字符开始输出该变量(跳过第一个逗号)。