【问题标题】:Identity Template confusion身份模板混淆
【发布时间】:2013-11-08 14:00:39
【问题描述】:

我正在尝试了解身份模板的功能。

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

如果上面的模板出现在我们的 XSL 文档的开头,我们称之为身份模板,它的功能是调用所有模板,即通过匹配 @* 和匹配中的 node() 下的所有内容。然后它转到第二行 apply-templates,它递归地选择所有模板/节点。如果我在这里错了,请纠正我。

我的问题是,如果我们把这个模板放在 XSLT 的中间,而不是在开始,我们不想要所有匹配的动作,而只想要存储在变量中的某个消息,比如

  <xsl:template match='$variable holding entire soap envelope'>
  <xsl:apply-templates select='@* | node()'/>
  </xsl:template>

我们是否仍将其称为身份模板,并且在第一次操作时它仍会像身份模板一样处理吗?

对不起,如果我的问题不清楚。

感谢您的帮助。

【问题讨论】:

    标签: xslt xslt-1.0


    【解决方案1】:

    不,覆盖身份转换的模板本身不会被视为身份转换。

    使用身份转换模板的方法是让它默认复制从输入 XML 到输出 XML 的所有内容,但在需要时使用更具体的 match 模式覆盖身份转换。

    例如,考虑以下 SOAP 消息:

    <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
      <env:Header>
        <n:alertcontrol xmlns:n="http://example.org/alertcontrol">
          <n:priority>1</n:priority>
          <n:expires>2001-06-22T14:00:00-05:00</n:expires>
        </n:alertcontrol>
      </env:Header>
      <env:Body>
        <m:alert xmlns:m="http://example.org/alert">
          <m:msg>Pick up Mary at school at 2pm</m:msg>
        </m:alert>
      </env:Body>
    </env:Envelope>
    

    如果我们想将此消息转换为几乎相同的另一个,但可能具有不同的m:msg 内容,我们可以使用具有m:msg 覆盖的身份转换:

    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:m="http://example.org/alert">
      <xsl:output omit-xml-declaration="yes" indent="yes"/>
      <xsl:strip-space elements="*"/>
    
      <xsl:template match="node()|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="m:msg">
        <xsl:copy>***Pick up Mary at school at 1pm, not 2pm.***</xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    将上述 XSLT 应用于输入 SOAP 消息会生成相同的 SOAP 消息,但具有新的m:msg 元素内容:

    <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
       <env:Header>
          <n:alertcontrol xmlns:n="http://example.org/alertcontrol">
             <n:priority>1</n:priority>
             <n:expires>2001-06-22T14:00:00-05:00</n:expires>
          </n:alertcontrol>
       </env:Header>
       <env:Body>
          <m:alert xmlns:m="http://example.org/alert">
             <m:msg>***Pick up Mary at school at 1pm, not 2pm.***</m:msg>
          </m:alert>
       </env:Body>
    </env:Envelope>
    

    【讨论】:

      【解决方案2】:

      身份转换模板复制每个节点,使其看起来像

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

      至于以 match='$variable' 之类的变量引用开头的匹配模式,我认为这在 XSLT 1.0 中是不允许的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-08-13
        • 2012-02-25
        • 2018-06-04
        • 2014-02-12
        • 1970-01-01
        • 2021-06-08
        • 1970-01-01
        • 2011-05-17
        相关资源
        最近更新 更多