我有一些XML,它们表示某些文本的两个替代版本,并且我正在使用XSLT执行选择一个或其他版本的修改。此外,一个替代方案还包含一个占位符,应将其替换为其他一些文本。
XSLT是通过编程生成的,本质上是一个身份转换,带有几个额外的模板,可以执行必要的调整。但是,当XSLT将替代项与占位符匹配时,将不会应用占位符模板,也不会填充该占位符。
实际的代码使用python的lxml,但是我主要是通过XML插件在notepad ++中测试XSLT。插件使用lxml之类的libxml2和libxslt,因此它们应该没有什么不同。
我尝试将<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>
答案 0 :(得分:1)
未应用模板,因为您从未在xsl:apply-templates
指令中选择与其匹配的节点。这是因为您的match="sn:alts"
不适用于其子级模板。
顺便说一句,processing-instruction
应该是processing-instruction()
。
答案 1 :(得分:0)
<xsl:stylesheet version = "2.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:sn="http://some.namespace" xmlns:html="http://www.w3.org/1999/xhtml">
<xsl:strip-space elements="*"/>
<xsl:output method = "xml" indent = "yes" />
<xsl:template match="sn:text">
<xsl:copy>
<p>
<xsl:apply-templates select="html:p/sn:alts/sn:alt[@sn:id = 'alt_2']"/>
<xsl:apply-templates select="html:p/text()"/>
</p>
</xsl:copy>
</xsl:template>
<xsl:template match="sn:alt[@sn:id = 'alt_2']">
<xsl:text>xyz </xsl:text><xsl:value-of select="."/><xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
You may try it.
答案 2 :(得分:0)
您要尝试实现的逻辑如下:
在这种情况下,请尝试以下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:alt[@sn:id='alt_2']]/sn:alt[@sn:id='alt_1']" />
<xsl:template match="sn:*">
<xsl:apply-templates />
</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>