如何使用 XSLT-1 将标记与格式化文本分开



我需要将混合的"标签和文本"XML拆分为两个"纯"部分:一部分只有数据标签(任何不是<b><i><sup>格式标签的标签);另一部分只有"文本"(//text()和格式标签)。

输入示例:

  <root>
    Nonono <i>nonon</i> <data1/> <b>nono</b> 
    <data2>nononono <i>no</i>nononon</data2>.
    <data3>blablabla<data4/></data3>
  </root>

输出示例:

  <root>
    <myTags>
       <data1/>
       <data2>nononono <i>no</i>nononon</data2>
       <data3>blablabla<data4/></data3>  
    </myTags>
    <myText>
      Nonono <i>nonon</i> <b>nono</b> 
      nononono <i>no</i>nononon . blablabla
    </myText>
  </root>

使用一个更现实的输入进行编辑,

    Nonono <i>nonon</i> <data1/> <b>nono <data66/> </b> 

必须输出

       <data1/><data66/>

这种情况表达了一个稍微复杂的问题。它可以发生在任何级别。


在我的 XSLT 的xsl:transform核心下方(那行不通!

<xsl:template match="/">
    <root>
    <myTags><xsl:call-template name="copyOnlyTags"/></myTags>
    <myText><xsl:call-template name="copyOnlyTextAndFormat"/></myText>
    </root>
</xsl:template>
<!-- LIB -->
<xsl:template name="copyOnlyTags">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:for-each select="node()[not(self::text())]">
        <xsl:choose>
          <xsl:when test="count(*)=0">    <!-- terminal -->
            <xsl:copy-of select="."/>
          </xsl:when>
          <xsl:otherwise>        <!-- recurrence -->
            <xsl:call-template name="copyOnlyTags"/>
          </xsl:otherwise>
        </xsl:choose>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>
<xsl:template name="copyOnlyTextAndFormat">
        <xsl:for-each select="node()">
        <xsl:choose>
          <xsl:when test="self::text()">
            <xsl:value-of select="."/>
          </xsl:when>
          <xsl:when test="name()='i' or name()='sup' or name()='sub' or name()='b'">
            <xsl:copy-of select="."/><!-- suppose only text into -->
          </xsl:when>
          <xsl:otherwise>        <!-- recurrence -->
            <xsl:call-template name="copyOnlyTextAndFormat"/>
          </xsl:otherwise>
        </xsl:choose>
        </xsl:for-each>
</xsl:template>

XSLT 不是告诉处理器你想要它做什么,而是说明你想要得到什么结果。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" />
  <xsl:template match="root">
    <xsl:copy>
      <myTags>
        <xsl:apply-templates select="node()" mode="data" />
      </myTags>
      <myText>
        <xsl:apply-templates select="node()" mode="format" />
      </myText>
    </xsl:copy>
  </xsl:template>
  <!-- unless stated otherwise, we want no output -->
  <xsl:template match="node()" mode="data" />
  <xsl:template match="node()" mode="format" />
  <!-- DATA MODE: data elements should be copied -->
  <xsl:template match="*[starts-with(name(), 'data')]" mode="data">
    <xsl:copy-of select="." />
  </xsl:template>
  <!-- DATA MODE: format elements should be passed silently -->
  <xsl:template match="*[not(starts-with(name(), 'data'))]" mode="data">
    <xsl:apply-templates select="node()" mode="data" />
  </xsl:template>
  <!-- FORMAT MODE: format elements and text nodes should be copied -->
  <xsl:template match="text() | *[not(starts-with(name(), 'data'))]" mode="format">
    <xsl:copy>
      <xsl:apply-templates select="node()" mode="format" />
    </xsl:copy>
  </xsl:template>
  <!-- FORMAT MODE: data elements should be passed silently -->
  <xsl:template match="*[starts-with(name(), 'data')]" mode="format">
    <xsl:apply-templates select="node()" mode="format" />
  </xsl:template>
</xsl:stylesheet>

<root>
    Nonono <i>nonon</i> <data1/> <b>nono</b> 
    <data2>nononono <i>no</i>nononon</data2>.
    <data3>blablabla<data4/></data3>
</root>

输出为

<root>
  <myTags>
    <data1/>
    <data2>nononono <i>no</i>nononon</data2>
    <data3>blablabla<data4/></data3>
  </myTags>
  <myText>
    Nonono <i>nonon</i>  <b>nono</b> 
    nononono <i>no</i>nononon.
    blablabla
  </myText>
</root>

<root>
    Nonono <i>nonon</i> <data1/> <b>nono <data66/> </b> 
</root>

它产生

<root>
  <myTags>
    <data1/>
    <data66/>
  </myTags>
  <myText>
    Nonono <i>nonon</i>  <b>nono  </b> 
  </myText>
</root>

相关内容

  • 没有找到相关文章