为什么不应用XSLT模板?

问题描述 投票:1回答:3

我有一些XML代表某些文本的两个替代版本,我使用XSLT执行选择一个或其他版本的修改。此外,一个替代方案还包含一个占位符,应该替换为其他一些文本。

XSLT是以编程方式生成的,本质上是一个身份转换,带有一些额外的模板,可以执行必要的调整。但是,当XSLT与占位符匹配替代时,占位符模板不会应用,也不会填充。

实际代码使用的是python的lxml,但我一直在使用XML插件在notepad ++中测试XSLT。该插件使用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>
xslt
3个回答
1
投票

未应用该模板,因为您从未在xsl:apply-templates指令中选择它匹配的节点。那是因为你的match="sn:alts"不适用于其子女的模板。

顺便说一下,processing-instruction应该是processing-instruction()


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.

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

© www.soinside.com 2019 - 2024. All rights reserved.