Две обработки фазы: не производите пустые теги от обработки фазы 1 XSLT 2.0

У меня есть некоторые сложные преобразования XSLT 2.0. Я пытаюсь узнать, существует ли способ общего назначения гарантировать, что никакие пустые теги не производятся. Так... концептуально, заключительный этап обработки, которая рекурсивно удаляет все пустые теги. Я понимаю, что это могло быть сделано отдельным XSLT, который действительно только отфильтровывал пустые теги, но мне нужно было упаковать все это вместе в единственном.

9
задан Dimitre Novatchev 8 July 2010 в 03:29
поделиться

1 ответ

Это преобразование XSLT 2.0 показывает, как может выполняться многопроходная (в данном случае двухпроходная) обработка :

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

при применении к этому 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>

] Он создает результирующий документ на первом проходе (который фиксируется в переменной $ vPass1 ), в котором все элементы с содержанием, даже целым числом, удаляются из своего содержимого и пусты. Затем во втором проходе, применяемом в определенном режиме, все пустые элементы удаляются.

Результатом преобразования является :

<nums>
   <num>01</num>
   <num>03</num>
   <num>05</num>
   <num>07</num>
   <num>09</num>
</nums>

Обратите внимание на использование режимов и специальных режимов #all и #current .

Обновление: OP теперь хочет в комментарии удалить «рекурсивно» «все узлы, у которых нет непустых потомков».

Это можно реализовать проще, не используя явную рекурсию. Просто измените:

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

на:

 <xsl:template match="*[not(descendant::text())]" mode="non-empty"/>
8
ответ дан 4 December 2019 в 22:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: