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

时间:2013-10-22 11:56:09

标签: xml xslt-1.0

我需要将混合的“标签和文字”XML分成两个“纯”部分:一部分只包含数据标签(任何标签都不是<b><i>或{ {1}} format-tags); o其他部分包含“仅文本”(<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> 

这个案例表达了一个更复杂的问题。它可以发生在任何级别。


在我的XSLT的 <data1/><data66/> 核心下面(不工作!),

xsl:transform

1 个答案:

答案 0 :(得分:1)

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>