我想:
所以给出以下xml:
<t>
<tag foo="A">apples</tag>
<tag foo="C">oranges</tag>
<tag foo="B">trees</tag>
</t>
以下映射:
<xsl:variable name="myMap">
<entry key="A">1</entry>
<entry key="B">2</entry>
<entry key="C">3</entry>
</xsl:variable>
输出结果为:
<max>3</max>
另一个问题,为什么我不能缩进我的代码?我正在放置空格,但它不起作用。
答案 0 :(得分:3)
I此标准XSLT 1.0转换(最类似于您的方法):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vrtfMap">
<entry key="A" value="1"/>
<entry key="B" value="2"/>
<entry key="C" value="3"/>
<entry key="X" value="8"/>
</xsl:variable>
<xsl:variable name="vMap" select=
"document('')/*/xsl:variable[@name = 'vrtfMap']/*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@foo">
<xsl:attribute name="foo">
<xsl:value-of select="$vMap[@key = current()]/@value"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
应用于以下XML文档(因为您没有提供任何内容):
<t foo="X">
<a foo="A">
<b foo="B"/>
</a>
<c foo="C"/>
</t>
生成想要的正确结果:
<t foo="8">
<a foo="1">
<b foo="2"/>
</a>
<c foo="3"/>
</t>
解释:正确使用XSLT current()
功能。
<强> II。使用密钥加速的XSLT 1.0解决方案
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kValFromKey" match="entry/@value" use="../@key"/>
<xsl:variable name="vrtfMap">
<entry key="A" value="1"/>
<entry key="B" value="2"/>
<entry key="C" value="3"/>
<entry key="X" value="8"/>
</xsl:variable>
<xsl:variable name="vMap" select=
"document('')/*/xsl:variable[@name = 'vrtfMap']/*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@foo">
<xsl:variable name="vCur" select="."/>
<xsl:attribute name="foo">
<xsl:for-each select="document('')">
<xsl:value-of select="key('kValFromKey', $vCur)"/>
</xsl:for-each>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
当此转换应用于同一XML文档(上图)时,会生成相同的正确结果。
<强>解释强>:
使用<xsl:for-each select="document('')">
将当前文档设置为样式表,以便key()
函数将使用为此文档构建的密钥索引。
将模板中与模板匹配的节点保存在变量中,以便我们可以在xsl:for-each
- current()
中使用它,这里无法正确使用它,因为它获取当前节点xsl:for-each
运作。
更新:OP现已在评论中澄清他最大的问题是找到最大值。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vrtfMap">
<entry key="A" value="1"/>
<entry key="B" value="2"/>
<entry key="C" value="3"/>
</xsl:variable>
<xsl:variable name="vMap" select=
"document('')/*/xsl:variable[@name = 'vrtfMap']/*"/>
<xsl:template match="/">
<xsl:variable name="vDoc" select="."/>
<xsl:variable name="vFoosMapped"
select="$vMap[@key = $vDoc/*/*/@foo]"/>
<max>
<xsl:value-of select=
"$vFoosMapped
[not($vFoosMapped/@value > @value)]
/@value
"/>
</max>
</xsl:template>
</xsl:stylesheet>
当给出此XML文档时(OP提供的文档缺少单个顶级元素):
<t>
<tag foo="A">apples</tag>
<tag foo="C">oranges</tag>
<tag foo="B">trees</tag>
</t>
产生了想要的正确结果:
<max>3</max>
备注:在XSLT 1.0中计算最大值(或最小值 - 以类似方式)的更有效方法是:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vrtfMap">
<entry key="A" value="1"/>
<entry key="B" value="2"/>
<entry key="C" value="3"/>
</xsl:variable>
<xsl:variable name="vMap" select=
"document('')/*/xsl:variable[@name = 'vrtfMap']/*"/>
<xsl:template match="/">
<xsl:variable name="vDoc" select="."/>
<xsl:variable name="vFoosMapped"
select="$vMap[@key = $vDoc/*/*/@foo]"/>
<max>
<xsl:for-each select="$vFoosMapped">
<xsl:sort select="@value" data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="@value"/>
</xsl:if>
</xsl:for-each>
</max>
</xsl:template>
</xsl:stylesheet>
另一个问题,为什么我不能缩进我的代码?我正在放空间但是 它不起作用。
这是一个他们未能修复好几个月的SO漏洞。
很可能你正在使用IE浏览器。如果您的版本是9,请执行以下操作:
按F12。
在弹出的窗口中单击最右侧的菜单,然后选择:“文档模式:IE9标准”
现在您应该能够看到带缩进的代码。