2012-03-06 51 views
1

我想:XSLT转换列表,并采取最大

  1. 选择所有属性“富”,这是字符串值,和值存储在列表中。
  2. 使用我的xslt中的某个映射将这个列表中的属性“foo”的每个值转换为一个数字。
  3. 选择列表的最大值并输出该值。

因此,考虑以下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

max()函数在XSLT 1.0中不可用。你可以使用XSLT 2.0解决方案吗?如果是这样,为什么这个问题被标记为“xslt-1.0”? – 2012-03-06 04:12:54

+0

我看到了最大功能,但还没有使用它,因为我还没有设法通过第2步。所以,如果我不能使用XSLT 1.0中的最大功能,这将是艰难的:/ – Thirlan 2012-03-06 13:50:54

回答

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"/> 
    <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()功能。


二, 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文档(以上)应用中,相同的正确的结果产生

说明

  1. 使用<xsl:for-each select="document('')">到当前文档中设置样式表,从而使key()功能将使用这个文件建立的关键指标。

  2. 保存在模板中的变量相匹配,以便我们可以使用它xsl:for-each内的节点 - current()不能正确这里使用,因为它可以让上xsl:for-each运行当前节点。

UPDATE:该任择议定书已经澄清的评价是他最大的问题是找到最大。

<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顶部元件):

<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,请执行以下操作:

  1. 按F12。

  2. 在弹出点击最右边的菜单,选择窗口:“文档模式:IE9标准”

现在你应该可以看到代码的缩进。

+0

我道歉Dimitre 。 (1)时,我没有足够明确。我不想搜索和替换xml中的内容。我想根据一些映射在xml中找到最大值并仅输出一个值。我应该举一个例子。我已经更正了我的问题以举例。 – Thirlan 2012-03-06 13:42:13

+0

@ Thirlan:是的,我评论了你的问题中的一个矛盾 - 你说你很容易做到这一点。 – 2012-03-06 13:44:24

+0

@ Thirlan:还有一个矛盾:你说:“* 1和2很容易,我可以做选择和使用最大函数,2是真正的问题,似乎是非常困难*”。我以为你想要:** 3 **是真正的问题。请改正。 – 2012-03-06 13:49:08