XSLT for-each循环和具有不同模式的节点

时间:2013-01-22 17:03:24

标签: xml xslt xpath

我有以下xml数据结构要转换:

     <chapter>
          <title>Text</title>
          <subtitle>Text</subtitle>
          <paragraph>Text</paragraph>
          <paragraph>Text</paragraph>
          <subtitle>Text</subtitle>
          <paragraph>Text</paragraph>
          <other>Text</other>
      </chapter>

      <chapter>
          <title>Text</title>
          <paragraph>Text</paragraph>
          <paragraph>Text</paragraph>
          <paragraph>Text</paragraph>
          <other>Text</other>
      </chapter>

      <chapter>
          <title>Text</title>
          <paragraph>Text</paragraph>
          <subtitle>Text</subtitle>
          <paragraph>Text</paragraph>
          <paragraph>Text</paragraph>
          <other>Text</other>
      </chapter>

正如您所看到的,不同章节中的字幕没有永久模式。在输出中,我需要将字幕设置在与xml中的字段相同的位置。对于段落标记,我使用for-each循环。像这样:

<xsl:template match="chapter">
  <xsl:for-each select="paragraph">
    <xsl:value-of select="."/>
  </xsl:for-each>
</xsl:template>

现在,我需要按照它们在xml中的顺序设置上面的字幕,段落之间或之间的字幕。我怎样才能做到这一点?请帮忙!

2 个答案:

答案 0 :(得分:1)

使用

 <xsl:for-each select="paragraph">

您首先要删除所有段落元素,您可以将其更改为

<xsl:for-each select="*">

按顺序处理所有元素,但更好(或至少更惯用xslt)以避免for-each并改为使用apply-templates。

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


<xsl:template match="title">
Title: <xsl:value-of select="."/>
</xsl:template>


<xsl:template match="subtitle">
SubTitle: <xsl:value-of select="."/>
</xsl:template>


<xsl:template match="paragraph">
 <xsl:text>&#10;&#10;</xsl:text>
 <xsl:value-of select="."/>
<xsl:text>&#10;&#10;</xsl:text>
</xsl:template>

答案 1 :(得分:0)

会这样做吗?

<xsl:template match="chapter">
  <xsl:for-each select="paragraph | subtitle">
    <xsl:value-of select="."/>
  </xsl:for-each>
</xsl:template>

但正如David Carlisle指出的那样,典型的XSLT方法是将其拆分为模板,如果您想对某些模板进行特殊处理,这尤其有意义:

<xsl:template match="chapter">
   <xsl:apply-templates select="paragraph | subtitle" />
</xsl:template>

<xsl:template match="paragraph">
   <xsl:value-of select="." />
</xsl:template>

<xsl:template match="subtitle">
   <!-- do stuff with subtitles -->
</xsl:template>