xsl:如何混合身份转换和自定义规则?

时间:2018-04-26 16:24:43

标签: xslt

我有一个xml(带封面的书籍目录),我为其创建了一个xsl,它显示书籍就好像它们在书架上一样。

现在我想允许显示底层的xml。 我想过显示/隐藏一个textarea,我在其中使用标识规则编写了xml。

我该怎么办?我的意思是我已经为“/”和后代(“书籍”,“作者”)编写了规则,如果我添加一个身份规则,它会很好,直到它调用自己但是当我的一个自定义规则匹配时我会开始输出与自定义规则关联的文本。

修改

根据Martin Honnen和Michael Kay的建议,解决方案是使用模式。

<xsl:template match="/"> 
 <html> 
  <body> 
  ...
  <xsl:apply-templates select="foo"" /> 
  ...
  <textarea>
    <xsl:apply-templates select="//*"          mode="SERIALIZE" />
  </textarea>
  </body> 
 </html> 
</xsl:template>

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

注意mode =“SERIALIZE”:
  在调用应用模板时,
  在身份模板的定义和
  在递归调用自己的时候。

2 个答案:

答案 0 :(得分:1)

如果要显示输入节点的标记,则需要对其进行序列化。在支持XPath 3.1的XSLT 3中,您可以使用serialize函数来执行此操作,例如

<xsl:template match="book" mode="show">
  <pre>
    <xsl:value-of select="serialize(.)"/>
  </pre>
</xsl:template>

https://xsltfiddle.liberty-development.net/jyH9rM4/1有一个使用XSLT 3和serialize函数的示例,用于在HTML book结果元素内输出pre输入元素的标记。

使用早期版本的XSLT,您需要检查您的XSLT处理器是否提供或支持扩展功能,或者您需要使用XSLT来序列化节点,我建议依赖现有的库,如http://lenzconsulting.com/xml-to-string/xml-to-string.xsl,记录在案在http://lenzconsulting.com/xml-to-string/,正确地执行命名空间和转义是一项复杂的任务,这样的库比为元素和属性节点编写模板以生成一些标记的快速尝试更好。

另一方面,如果你真的想要使用HTML textarea,假设它的内容模型是文本,那么你可能会在textara元素中输出元素,例如<textarea><xsl:copy-of select="."/></textarea>或者如果您希望通过身份转换推动它。使用XSLT为同一匹配节点分隔两个模板的正确工具是使用名为mode的至少一个模板。在XSLT 1.0中,您还需要为该模式设置身份转换模板,在XSLT 2中,您可以更改身份转换模板,以便在mode="#all"xsl:template上使用mode="#current"内部xsl:apply-templates

https://xsltfiddle.liberty-development.net/gWmuiJ2/1有一个示例,只需将book元素作为HTML textarea元素的内容复制<xsl:copy-of select="."/>,浏览器似乎可以正常处理以显示XML标记。

答案 1 :(得分:1)

混合使用两种不同方式处理相同节点的方法是使用模式。您可以通过将不同的mode属性附加到模板规则来定义两种不同的处理模式,并且可以通过向mode指令添加xsl:apply-templates属性来启动特定模式的处理。 / p>