2

我是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>

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

4

2 回答 2

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
于 2012-09-01T18:26:38.233 回答
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>

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

于 2012-09-01T19:40:17.040 回答