У меня возникла интересная проблема, когда я пытаюсь последовательно соединить два преобразования по порядку (с использованием XSLT 2.0), чтобы удалить элементы CDATA из исходного XML на первом проходе, чтобы его можно было проанализировать как XML во втором. Хотя я сомневаюсь, что это повлияет на результат, я использую параметр начального шаблона в Saxon 9 HE и функцию collection (), чтобы собрать несколько XML-документов (одинаковые пространства имен) в переменную перед тем, как подвергнуть ее преобразованию. Стоит отметить, что сейчас я даже не могу заставить это работать с одним документом.
Мои входные документы:
<root>
<blah>
<![CDATA[<elementA att="A"><elementB att="B">Text</elementB></elementA>]]>
</blah>
</root>
Моя попытка XSLT:
<!-- Collect all XML files in $input folder for processing -->
<xsl:variable name="xml" select="collection(concat($input,'?select=*.*ml;recurse=no;on-error=ignore'))"/>
<!-- Initial template is called from the saxon command line using the -it:process option -->
<xsl:template name="process">
<!-- First pass -->
<xsl:variable name="pass1xml">
<xsl:apply-templates select="$xml" mode="pass1"/>
</xsl:variable>
<!-- First pass output -->
<xsl:result-document href="{concat($output,'\pass1.xml')}" method="xml" indent="yes">
<xsl:copy-of select="$pass1xml"/>
</xsl:result-document>
<!-- Second pass -->
<xsl:apply-templates select="$pass1xml" mode="pass2"/>
</xsl:template>
<!-- First pass: copy everything -->
<xsl:template match="@* | node()" mode="pass1">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="pass1"/>
</xsl:copy>
</xsl:template>
<!-- First pass: strip CDATA from element -->
<xsl:template match="blah" mode="pass1">
<xsl:copy>
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:copy>
</xsl:template>
<!-- Second pass using $pass1xml variable -->
<xsl:template match="root" mode="pass2">
<!-- Second pass output -->
<xsl:result-document href="{concat($output,'\pass2.xml')}" method="xml" indent="yes">
<xsl:apply-templates select="descendant::elementA" mode="elementA"/>
</xsl:result-document>
</xsl:template>
...etc (continue with second pass)...
Желаемый результат первого прохода:
<root>
<blah>
<elementA att="A">
<elementB att="B">Text</elementB>
</elementA>
</blah>
</root>
То, что я сейчас вижу в моем pass1.xml (результат первого прохода - несмотря на использование disable-output-escaping = "yes"), - это экранированный XML, который, очевидно, не является XPATHable в pass2:
<root>
<blah>
<elementA att="A"><elementB att="B">Text</elementB></elementA>
</blah>
</root>
К сожалению, я не могу изменить исходный документ, чтобы удалить CDATA (я ценю, что это решит мою проблему). XML в CDATA тоже всегда будет правильно сформирован, поэтому я не сомневаюсь в его удалении. Возможно, я неправильно понимаю подход гирляндной цепи, что означает, что то, чего я пытаюсь достичь, невозможно - в любом случае я очень хочу научиться.
Большое спасибо за ваше время и советы - это очень важно!