我有以下XSL模板(我省略了组织模板,请告诉我是否有必要):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:output method="html" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="SOAP-ENV:Body/*[local-name()='Publisher']">
<html>
<xsl:call-template name="body" />
</html>
</xsl:template>
<xsl:template name="body">
<BODY>
<br/>
<center>
<font face="arial" size="2">
<b>Publisher <xsl:value-of select="*[local-name()='Organization']/*[local-name()='PublisherData']/*[local-name()='PublisherName']"/>
</b>
</font>
</center>
<br/>
<xsl:apply-templates select="*[local-name()='Organization']"/>
</BODY>
</xsl:template>
</xsl:stylesheet>
上一个模板生成我想要的输出,它生成包含“body”模板生成的输出的标签。我遇到的问题是在开始标记之前我从前一个节点获得文本输出。不知道为什么会发生这种情况,因为我没有选择其他节点。例如:
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Header>
<n1>abc</n1>
<n2>def</n2>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<Publisher>
<!--Child nodes here -->
</Publisher>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
鉴于前面的示例XML片段,我的输出将包含我期望格式化Publisher元素的内容,但我也得到了SOAP-ENV:Header节点的子节点的文本节点。
我只想转换Publisher元素的内容,但在输出中我会得到:
abc
def
//Expected output transforming Publisher goes here
我的问题是,为什么选择abc和def?
答案 0 :(得分:3)
正在生成输出,因为built in template rules:
XSLT 1.0建议书的相关部分包含在下面。
您可能只想为SOAP-ENV:Header做一个无用的模板。
<xsl:template match="SOAP-ENV:Header">
</xsl:template>
源文档中的某些元素不在命名空间中。在XPath表达式中,没有名称空间的元素可以通过其文字本地名称引用。如果您不知道元素的命名空间,则只需使用local-name()
。
以下是样式表的修改版本。它以匹配/
的模板开头,然后显式选择我们想要的节点。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:output method="html" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<html>
<xsl:apply-templates select="SOAP-ENV:Body/Publisher" />
</html>
</xsl:template>
<xsl:template name="Publisher">
<body>
<br/>
<center>
<font face="arial" size="2">
<b>
<xsl:text>Publisher </xsl:text>
<xsl:value-of select="Organization/PublisherData/PublisherName"/>
</b>
</font>
</center>
<br/>
<xsl:apply-templates select="Organization"/>
</body>
</xsl:template>
</xsl:stylesheet>
内置模板规则
有一个内置的模板规则 允许递归处理继续 在没有成功模式的情况下 匹配显式模板规则 样式表。此模板规则 适用于两个元素节点和 根节点。以下显示了 相当于内置模板 规则:
<xsl:template match="*|/"> <xsl:apply-templates/> </xsl:template>
还有一个内置模板规则 对于每种模式,它允许递归 处理继续在同一个 模式在没有成功的情况下 模式匹配显式模板 样式表中的规则。这个模板 规则适用于两个元素节点和 根节点。以下显示了 相当于内置模板 模式m的规则。
<xsl:template match="*|/" mode="m"> <xsl:apply-templates mode="m"/> </xsl:template>
还有一个内置模板规则 对于文本和属性节点 通过以下方式复制文本:
<xsl:template match="text()|@*"> <xsl:value-of select="."/> </xsl:template>
内置模板规则 处理说明和评论 是什么都不做。
<xsl:template match="processing-instruction()|comment()"/>
内置模板规则 命名空间节点也无所作为。 没有可以匹配的模式 名称空间节点所以,内置 模板规则是唯一的模板 应用于命名空间的规则 节点
内置模板规则是 如同进口一样对待 隐式地在样式表之前和 因此导入优先级低于 所有其他模板规则。就这样 作者可以覆盖内置的 模板规则通过包含显式 模板规则。