XSLT2 - 获取除某些节点之外的所有节点的文本

时间:2016-06-10 07:10:18

标签: xml xslt

我正在尝试获取整个HTML外观文档的文本,但我想从检索中排除某些节点。

XML

<body>
  <p>some text</p>
  <p>some text <img src="whatever"><alt>alt title</alt></p>
  <div>
     <p>some text</p>
  </div>
</body>

上下文

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xsl:template match="/">

   <html>
     <body>
       <table>
         <xsl:for-each select="collection(...)"> 
           <xsl:variable name="text" select="string(//body)" />
              <tr>
                 <td><xsl:value-of select="$text"/></td>
              </tr>
          </xsl:for-each>
        <table>
      </body>
   </html>

  </xsl:template>
</stylesheet>

预期结果

除了alt元素之外我想要的所有内容都是some text * 3 = 29。

我正在for-each文件的collection上执行此操作。 所以现在我只需要string(/body)来获取我的每个文件中的所有内容。

我在想一个递归的电话:

 <xsl:function name="lp:gettext">
    <xsl:param name="n" />
    <xsl:choose>
      <xsl:when test="$n/child::node()">
        <xsl:value-of select="concat(text(),lp:gettext($n/child::node()))" />
      </xsl:when>
      <xsl:when test="$n/name()='alt'" />
      <xsl:otherwise>
        <xsl:value-of select="text()" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>

但我似乎无法在一个函数中使用child::,或者不像我一样。

我怎样才能达到我想做的目的?

2 个答案:

答案 0 :(得分:1)

应用以下样式表:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="alt"/>

</xsl:stylesheet>

输入(关闭img标签后!)返回:

<?xml version="1.0" encoding="UTF-8"?>
some textsome text some text

这是因为built-in template rules将所有文本节点复制到输出 - 所以您需要做的就是覆盖您不想复制的节点的默认行为。

加了:

根据您添加到问题中的样式表,我相信以下内容应该符合您的要求(我无法测试):

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <html>
        <body>
            <table>
                <tr>
                    <td>
                        <xsl:apply-templates select="collection(...)"/>
                    </td>
                </tr>
            <table>
        </body>
    </html>
</xsl:template>

<xsl:template match="alt"/>

</xsl:stylesheet>

答案 1 :(得分:0)

好的,我刚刚发现这个remove-elements-deep函数似乎正是我想要的。