Map xslt转换列表和take max
我想:Map xslt转换列表和take max,map,transform,xslt-1.0,Map,Transform,Xslt 1.0,我想: 选择所有属性“foo”,它们是字符串值,并将值存储在列表中 使用xslt中的一些映射将此列表中属性“foo”的每个值转换为一个数字 选择列表的最大值并输出该值 因此,给定以下xml: <t> <tag foo="A">apples</tag> <tag foo="C">oranges</tag> <tag foo="B">trees</tag> </t> 苹果 橘子
<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>
1.
2.
3.
产出将是:
<max>3</max>
3
另一个问题,为什么我不能缩进我的代码?我放置了空格,但它不起作用。我使用了标准XSLT 1.0转换(最类似于您的方法): 当此转换应用于相同的XML文档(如上)时,会产生相同的正确结果 说明:
<t foo="8">
<a foo="1">
<b foo="2"/>
</a>
<c foo="3"/>
</t>
<max>3</max>
将当前文档设置为样式表,以便key()
函数将使用为此文档构建的键索引xsl:for each
中使用它--current()
在这里不能正确使用,因为它获取xsl:for each
操作的当前节点<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提供的文档缺少singlr top元素):
苹果
橘子
树
生成所需的正确结果:
<t foo="8">
<a foo="1">
<b foo="2"/>
</a>
<c foo="3"/>
</t>
<max>3</max>
3
备注:在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>
另一个问题,为什么我不能缩进我的代码?我在放空格,但是
它不起作用了
这是一个如此严重的错误,以至于他们几个月都未能修复
您很可能正在使用IE。如果您的版本是9,请执行以下操作:
<t foo="8">
<a foo="1">
<b foo="2"/>
</a>
<c foo="3"/>
</t>
<max>3</max>
现在您应该可以看到缩进代码。XSLT1.0中没有
max()
函数。您可以使用XSLT2.0解决方案吗?如果是这样的话,为什么这个问题被标记为“xslt-1.0”?我看到了max函数,但还没有使用它,因为我还没有通过步骤2。因此,如果我不能在XSLT1.0中使用max函数,这将很困难:/Dimitre,我道歉。我在陈述(1)时不够明确。我不想搜索和替换xml中的内容。我想根据一些映射在xml中找到最大值,并只输出一个值。我真的应该举个例子。我已经更正了我的问题以给出示例。@Thirlan:是的,我对你问题中的一个矛盾进行了评论——你说你很容易做到。@Thirlan:仍然有一个矛盾:你说:“1和2很容易。我可以选择并使用最大值函数。2是真正的问题,似乎非常困难。”。我以为你想说:3才是真正的问题。请说对。对不起,我已经把我的观点和垃圾从这个问题上去掉了。我希望有例子的问题是清楚的。另外,如果这仅在xslt 2.0中可行,那么我将非常感谢2.0中的解决方案,我只需要找出如何使2.0在我的机器上工作。@Thirlan:我已经更新了我的答案(请看接近结尾的部分),并为您真正的问题提供了解决方案。至于XSLT 2.0——安装并使用它,尽管我给了您一个XSLT 1.0解决方案——您应该感谢我的建议:)