为什么不应用XSLT模板?

时间:2019-03-27 12:23:00

标签: xslt

我有一些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>

3 个答案:

答案 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)

您要尝试实现的逻辑如下:

  1. 如果存在“ alt_2”,则输出该内容(对占位符进行修改),并忽略“ alt_1”
  2. 否则输出“ alt_1”

在这种情况下,请尝试以下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>

请参见http://xsltfiddle.liberty-development.net/ncdD7mo