身份模板混淆

时间:2013-11-08 14:00:40

标签: xslt xslt-1.0

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

  <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>

我们仍然将其称为身份模板,并且在第一次操作中它仍然会像身份模板一样处理。?

很抱歉,如果我的问题不明确。

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:2)

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

使用身份转换模板的方法是让默认情况下将所有内容从输入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内容,我们可以使用带有覆盖的身份转换{{ 1}}

m:msg

将上述XSLT应用于输入SOAP消息会生成相同的SOAP消息,但<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> 元素内容

m:msg