XSL:包装所有子代文本和元素



给定以下XML文档:

<dialog>
  <speech speaker="Robert">
    <line>"Once more into the breach", he said.</line>
    I can't believe him. I just <emphasis>can't</emphasis> believe him!
  </speech>
</dialog>

我想尝试捕获speech中不在line中的每一个元素,并将其封装在line中,但我需要捕获任何其他元素(例如,上面示例中的emphasis)。

我想达到的结果是:

<dialog>
  <speech speaker="Robert">
    <line>"Once more into the breach", he said.</line>
    <line>I can't believe him. I just <emphasis>can't</emphasis> believe him!</line>
  </speech>
</dialog>

我使用的是libxsltlibxml,所以我一直使用XSLT1.0。

XSLT1.0中实现这一点的一种方法是通过同级递归,如下例所示:

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="@* | node()" name="identity">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="speech">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates select="node()[1]"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="speech/line">
  <xsl:call-template name="identity"/>
  <xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="speech/node()[not(self::line)
                                  and (not(preceding-sibling::node())
                                       or
                                       preceding-sibling::node()[1][self::line])]">
  <xsl:if test="normalize-space() or following-sibling::node()[1][not(self::line)]">
    <line>
      <xsl:call-template name="identity"/>
      <xsl:apply-templates select="following-sibling::node()[1][not(self::line)]"/>
    </line>
  </xsl:if>
  <xsl:apply-templates select="following-sibling::line[1]"/>
</xsl:template>
<xsl:template match="speech/node()[not(self::line)
                                   and preceding-sibling::node()[1][not(self::line)]]">
  <xsl:call-template name="identity"/>
  <xsl:apply-templates select="following-sibling::node()[1][not(self::line)]"/>
</xsl:template>
</xsl:stylesheet>

有了这个样式表,一个类似的输入示例

<dialog>
  <speech speaker="Robert">
    <line>"Once more into the breach", he said.</line>
    I can't believe him. I just <emphasis>can't</emphasis> believe him!
  </speech>
  <speech speaker="Foo">This is a test.
    <line>This line is wrapped and should be copied unchanged.</line>
    <em>This</em> needs to be <it>wrapped</it>.
  </speech>
  <speech speaker="Bar">   <em>This</em> should be wrapped.
    <line>This line is wrapped and should be copied unchanged.</line>
    <it>Test</it>
  </speech>
</dialog>

转化为

<dialog>
  <speech speaker="Robert"><line>"Once more into the breach", he said.</line><line>
    I can't believe him. I just <emphasis>can't</emphasis> believe him!
  </line></speech>
  <speech speaker="Foo"><line>This is a test.
    </line><line>This line is wrapped and should be copied unchanged.</line><line>
    <em>This</em> needs to be <it>wrapped</it>.
  </line></speech>
  <speech speaker="Bar"><line>   <em>This</em> should be wrapped.
    </line><line>This line is wrapped and should be copied unchanged.</line><line>
    <it>Test</it>
  </line></speech>
</dialog>

相关内容

  • 没有找到相关文章

最新更新