Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT模板覆盖_Xslt_Templates_Overriding - Fatal编程技术网

XSLT模板覆盖

XSLT模板覆盖,xslt,templates,overriding,Xslt,Templates,Overriding,我有一个关于XSLT模板覆盖的小问题。 对于我的XML的这一部分: <record> <medication> <medicine> <name>penicillin G</name> <strength>500 mg</strength> </medicine> </medication> </record> 青霉素G 50

我有一个关于XSLT模板覆盖的小问题。 对于我的XML的这一部分:

<record>
  <medication>
    <medicine>
      <name>penicillin G</name>
      <strength>500 mg</strength>
    </medicine>
  </medication>
</record>

青霉素G
500毫克
在我的XSLT工作表中,我有两个按以下顺序排列的模板:

 <xsl:template match="medication">
   <xsl:copy-of select="." />
   </xsl:template>
   <xsl:template match="medicine/name">
   <text>!unauthorized information!</text>
 </xsl:template>

!未经授权的信息!
我要做的是将medicing元素下的所有内容复制到输出,而不是“name”元素(或我显式定义的任何其他元素)。最终的xml将以原始xml形式显示给用户。换句话说,我想要的结果是:

<record>
  <medication>
    <medicine>
      <text>! unauthorized information!</text>
      <strength>500 mg</strength>
    </medicine>
  </medication>
</record>

! 未经授权的信息!
500毫克
然而,我得到的是与输入相同的XML,即没有用文本替换元素。你知道为什么第二个模板匹配没有覆盖第一个模板中的name元素吗?提前谢谢

-- 阿里

添加

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

到您的

然后将
一起删除

<?xml version="1.0" encoding="windows-1251"?>
<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">

 <xsl:template match="medicine/name">
   <text>!unauthorized information!</text>
 </xsl:template>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

!未经授权的信息!
添加


到您的

然后将
一起删除

<?xml version="1.0" encoding="windows-1251"?>
<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">

 <xsl:template match="medicine/name">
   <text>!unauthorized information!</text>
 </xsl:template>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

!未经授权的信息!

模板顺序无关紧要。唯一可能考虑的情况(这取决于处理器)是当您遇到无法解决的冲突时,即出现错误情况。在这种情况下,XSLT处理器通过选择最后一个错误来从错误中恢复是合法的。但是,您永远不应该编写依赖于此行为的代码

在您的情况下,模板优先级甚至不是问题。您有两个不同的模板规则,一个匹配
元素,另一个匹配
元素。它们永远不会冲突,所以这不是模板优先级或重写的问题。问题在于,您的代码从未实际将模板应用于
元素。当你在
上说
时,你是在说:“执行
的深度复制”。为子节点触发任何模板规则的唯一方法是显式应用模板(使用

我为您提供的解决方案与alamar的基本相同,只是它使用了一个单独的处理“模式”,将规则与样式表中的所有其他规则隔离开来。通用的
match=“@*|node()”
template使模板规则递归应用于子级(和属性),这使您有机会覆盖某些节点的行为

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- ...placeholder for the rest of your code... -->
  <xsl:template match="/record">
    <record>
      <xsl:apply-templates/>
    </record>
  </xsl:template>
  <!-- end of placeholder -->

  <xsl:template match="medication">
    <!-- Instead of copy-of, whose behavior is to always perform
         a deep copy and cannot be customized, define your own
         processing mode. Rules with this mode name are isolated
         from the rest of your code. -->
    <xsl:apply-templates mode="copy-medication" select="."/>
  </xsl:template>

          <!-- By default, copy all nodes and their descendants -->
          <xsl:template mode="copy-medication" match="@* | node()">
            <xsl:copy>
              <xsl:apply-templates mode="copy-medication" select="@* | node()"/>
            </xsl:copy>
          </xsl:template>

          <!-- But replace <name> -->
          <xsl:template mode="copy-medication" match="medicine/name">
            <text>!unauthorized information!</text>
          </xsl:template>

</xsl:stylesheet>

!未经授权的信息!
medicine/name
”的规则覆盖“
@*| node()
”的规则,因为模式的格式(包含“
/
”)使其默认优先级(0.5)高于“
node()
”(-1.0)的默认优先级

关于模板优先级如何工作的完整而简洁的描述可以在我的网站上找到


最后,我注意到您提到您希望向用户显示“原始XML”。这是否意味着您希望在浏览器中显示,例如,包含所有开始和结束标记的XML?在这种情况下,您需要转义所有标记(例如,“
模板顺序”的“
”。唯一可能考虑的情况是(这取决于处理器)是指出现无法解决的冲突,即错误情况。在这种情况下,XSLT处理器通过选择最后一个错误来从错误中恢复是合法的。但是,您永远不应该编写依赖于此行为的代码

在您的情况下,模板优先级甚至不是问题。您有两个不同的模板规则,一个是匹配的
元素,另一个是匹配的
元素。这些元素永远不会冲突,因此这不是模板优先级或重写的问题。问题是您的代码从未将模板实际应用于
元素。当您在
上说
时,您的意思是:“执行
的深度复制”。为子节点触发任何模板规则的唯一方法是显式应用模板(使用

我为您提供的解决方案与alamar的基本相同,只是它使用了一个单独的处理“模式”,将规则与样式表中的所有其他规则隔离开来。通用的
match=“@*|node()”
template使模板规则递归应用于子级(和属性),这使您有机会覆盖某些节点的行为

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- ...placeholder for the rest of your code... -->
  <xsl:template match="/record">
    <record>
      <xsl:apply-templates/>
    </record>
  </xsl:template>
  <!-- end of placeholder -->

  <xsl:template match="medication">
    <!-- Instead of copy-of, whose behavior is to always perform
         a deep copy and cannot be customized, define your own
         processing mode. Rules with this mode name are isolated
         from the rest of your code. -->
    <xsl:apply-templates mode="copy-medication" select="."/>
  </xsl:template>

          <!-- By default, copy all nodes and their descendants -->
          <xsl:template mode="copy-medication" match="@* | node()">
            <xsl:copy>
              <xsl:apply-templates mode="copy-medication" select="@* | node()"/>
            </xsl:copy>
          </xsl:template>

          <!-- But replace <name> -->
          <xsl:template mode="copy-medication" match="medicine/name">
            <text>!unauthorized information!</text>
          </xsl:template>

</xsl:stylesheet>

!未经授权的信息!
medicine/name
”的规则覆盖“
@*| node()
”的规则,因为模式的格式(包含“
/
”)使其默认优先级(0.5)高于“
node()
”(-1.0)的默认优先级

关于模板优先级如何工作的完整而简洁的描述可以在我的网站上找到


最后,我注意到您提到要向用户显示“原始XML”。这是否意味着您要在浏览器中显示,例如,包含所有开始和结束标记的XML?在这种情况下,您需要转义所有标记(例如,“
”for”
感谢您的回复alamar。我无法删除药物模板,因为这只是包含许多其他元素的较大XML的一块。因此,首先我想说显示所有药物元素的原样,但如果有任何模板规则遵循,如名称规则,则用文本替换。希望这能澄清问题。您也可以声明谢谢你的回复,阿拉玛。我不能移除医生