0

给定以下 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并将其包装在 a 中line,但是我需要捕获任何其他元素以及它(emphasis例如上面示例中的 the )。

我想要达到的结果是:

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

我正在使用libxsltand libxml,所以我坚持使用 XSLT 1.0。

4

1 回答 1

2

在 XSLT 1.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>
于 2013-07-22T12:16:24.573 回答