两阶段处理:不要从阶段1 XSLT 2.0处理中输出空标记

men*_*ics 9 xslt xslt-2.0

我有一些复杂的XSLT 2.0转换.我试图找出是否有通用的方法来确保不输出空标签.所以......从概念上讲,处理的最后阶段会递归删除所有空标记.我知道这可以通过一个单独的XSLT来完成,它除了过滤掉空标签之外什么也没做,但是我需要将它们全部打包在一起.

Dim*_*hev 8

这个XSLT 2.0转换说明了如何完成多遍(在这种情况下是2遍)处理:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*" mode="#all">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*" mode="#current"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/">
   <xsl:variable name="vPass1">
     <xsl:apply-templates/>
   </xsl:variable>

   <xsl:apply-templates select="$vPass1/*" mode="non-empty"/>
 </xsl:template>

 <xsl:template match="text()[xs:integer(.) mod 2 eq 0]"/>

 <xsl:template match="*[not(node())]" mode="non-empty"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

应用于此XML文档时:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>
Run Code Online (Sandbox Code Playgroud)

它在第一遍中创建一个结果文档(在$vPass1变量中捕获),其中<num>包含内容甚至整数的所有元素都从其内容中删除并为空.然后,在以特定模式应用的第二遍中,移除所有空元素.

转型的结果是:

<nums>
   <num>01</num>
   <num>03</num>
   <num>05</num>
   <num>07</num>
   <num>09</num>
</nums>
Run Code Online (Sandbox Code Playgroud)

请注意模式的使用,以及特殊模式#all#current.

更新: OP现在希望在注释中"递归地"删除"没有非空后代的所有节点".

这可以使用没有显式递归更简单地实现.只是改变:

 <xsl:template match="*[not(node())]" mode="non-empty"/>
Run Code Online (Sandbox Code Playgroud)

至:

 <xsl:template match="*[not(descendant::text())]" mode="non-empty"/>
Run Code Online (Sandbox Code Playgroud)