У меня есть некоторый XML, который представляет две альтернативные версии некоторого текста, и я использую XSLT для выполнения модификации, которая выбирает ту или иную версию.Кроме того, одна альтернатива также содержит заполнитель, который должен быть заменен другим битом текста.
XSLT генерируется программно и, по сути, представляет собой преобразование идентичности с парой дополнительных шаблонов, которые выполняют необходимые настройки.Однако, когда XSLT сопоставляет альтернативу с заполнителем, шаблон заполнителя не применяется и никогда не заполняется.
Фактический код использует lxml python, но я в основном тестировал XSLT в notepad ++ сXML-плагин.Плагин использует libxml2 и libxslt, например lxml, поэтому они не должны отличаться.
Я пробовал добавлять различные версии <xsl:apply-template />
в шаблон 2, но ничего не приводит к тому, что заполнитель получает значение, которое яОжидайте
Ниже приведена очень урезанная версия XML:
<sn:text xmlns:sn="http://some.namespace" xmlns="http://www.w3.org/1999/xhtml">
<p>
<sn:alts sn:id="alts_1">
<sn:alt sn:id="alt_1">start 1</sn:alt>
<sn:alt sn:id="alt_2">
<sn:placeholder sn:id="p_1"/> start 2</sn:alt>
</sn:alts> blah blah blah...</p>
</sn:text>
И вот сгенерированный XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" xmlns:sn="http://some.namespace">
<!--template 1-->
<xsl:template match="sn:placeholder[@sn:id='p_1']">XYZ</xsl:template>
<!--template 2-->
<xsl:template match="sn:alts[@sn:id='alts_1']">
<xsl:value-of select="sn:alt[@sn:id='alt_2']" />
</xsl:template>
<!--identity transform-->
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|text()|comment()|processing-instruction">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
В результате яожидание должно быть примерно таким:
<sn:text xmlns:sn="http://some.namespace" xmlns="http://www.w3.org/1999/xhtml">
<p>XYZ start 2 blah blah blah...</p>
</sn:text>
Вместо этого заполнитель не заменяется на "XYZ", а полностью исключается:
<sn:text xmlns:sn="http://some.namespace" xmlns="http://www.w3.org/1999/xhtml">
<p> start 2 blah blah blah...</p>
</sn:text>
Обновление
Спасибо за указатели.В конце концов, это было совершенно очевидно:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" xmlns:sn="http://some.namespace">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes" />
<!--template 1-->
<xsl:template match="sn:placeholder[@sn:id='p_1']">XYZ</xsl:template>
<!--template 2-->
<xsl:template match="sn:alts[@sn:id='alts_1']">
<xsl:apply-templates select="sn:alt/sn:placeholder"/>
<xsl:value-of select="sn:alt[@sn:id='alt_1']" />
</xsl:template>
<!--identity transform-->
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|text()|comment()|processing-instruction()">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>