如何从标记存储在变量中的树中选择节点?

时间:2010-08-25 09:11:07

标签: xslt

考虑以下XSLT脚本:

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

<xsl:output method="text" encoding="iso-8859-1"/>

<xsl:variable name="stringmap">
<map>
<entry><key>red</key><value>rot</value></entry>
<entry><key>green</key><value>gruen</value></entry>
<entry><key>blue</key><value>blau</value></entry>
</map>
</xsl:variable>

<xsl:template match="/">
<!-- IMPLEMENT ME -->
</xsl:template>

</xsl:stylesheet>

我希望此脚本能够打印redgreenblue

有没有办法将存储在stringmap变量中的XML标记视为自己的文档,我可以运行XPath查询?我基本上都在寻找像

这样的东西
<xsl:for-each select="document($stringmap)/map/entry">
    <xsl:value-of select="key"/>
</xsl:for-each>

document()函数需要URI)。

动机:我有各种长<xsl:choose>个元素,它们将给定的字符串映射到另一个字符串。我想用一个带有'map'参数的模板(这是一个简单的XML文档)替换所有这些模板。我希望我可以用<xsl:choose>

之类的简单语句替换<xsl:value-of select="$stringmap/map/entry/value[../key='$givenkey']"/>

我正在使用xsltproc使用XSLT 1.0。

2 个答案:

答案 0 :(得分:5)

你几乎是对的,使用document('')将允许你处理当前样式表中的节点集:

<xsl:for-each select="document('')/xsl:stylesheet/xsl:variable[@name='stringmap']/map/entry">
    <xsl:value-of select="key"/>
</xsl:for-each>

在这种情况下,没有必要将map节点集定义为变量:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:data="some.uri" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <data:map>
    <entry><key>red</key><value>rot</value></entry>
    <entry><key>green</key><value>gruen</value></entry>
    <entry><key>blue</key><value>blau</value></entry>
  </data:map>

  <xsl:template match="/">
    <xsl:for-each select="document('')/xsl:stylesheet/data:map/entry">
      <xsl:value-of select="key"/>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

如果不使用xsl:variable作为包装器,则必须记住顶级元素必须具有非空名称空间URI。

在XSLT 2.0中,可以只迭代变量中的内容:

<xsl:variable name="map">
  <entry><key>red</key><value>rot</value></entry>
  <entry><key>green</key><value>gruen</value></entry>
  <entry><key>blue</key><value>blau</value></entry>
</xsl:variable>

<xsl:template match="/">
  <xsl:for-each select="$map/entry">
    <xsl:value-of select="key"/>
  </xsl:for-each>
</xsl:template>

答案 1 :(得分:0)

A posting by M. David Peterson刚刚教我如何做这项工作:

对于这种情况,没有必要<xsl:variable>。相反,我可以将数据文档直接嵌入到XSL样式表中(将其放入名称空间中以获得完整性),然后从中选择元素。结果如下:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:map="uri:map">

<xsl:output method="text" encoding="iso-8859-1"/>

<map:colors>
<entry><key>red</key><value>rot</value></entry>
<entry><key>green</key><value>gruen</value></entry>
<entry><key>blue</key><value>blau</value></entry>
</map:colors>

<xsl:template match="/">
<xsl:for-each select="document('')/*/map:colors/entry">
    <xsl:value-of select="key"/>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

这会生成预期的输出redgreenblue

诀窍是使用document('')获取XSLT文档本身的句柄,然后*进入顶级xsl:stylesheet元素,然后我可以访问颜色映射。