1

我知道这是多次发布的一个常见问题,但不幸的是,我无法使用任何建议的方法找到确切的解决方案:

这是我的 XML 的样子:

<root>
  <parent>
    <table>
    <attr ......>
       <type t="enumone">
       <info>
        <name .....>
       </info>
    </attr>

    <attr>
        <type t="int">
        <range min="1" max="255"/>
         </type>
         <info>
        <name .....>
       </info>
    </attr>

    <attr>
        <type t="string">
         <info>
        <name .....>
       </info>
    </attr> 
    <attr ......>
       <type t="enumtwo">
       <info>
        <name .....>
       </info>
    </attr>

    <attr>
        <type t="float">
        <range min="1.0" max="25.5"/>
         </type>
         <info>
        <name .....>
       </info>
    </attr>

    <attr>
        <type t="int">
         <info>
        <name .....>
       </info>
    </attr> 


    <attr>
        <type t="enumone">
         <info>
        <name .....>
       </info>
    </attr> 
    <attr>
        <type t="enumthree">
         <info>
        <name .....>
       </info>
    </attr> 
    <attr>
        <type t="enumone">
         <info>
        <name .....>
       </info>
    </attr> 
    </parent>
 </root>

目的是使用 XSLT 从“type”元素中检索一次出现的属性“@t”:

Using for-each-group:
<xsl-template match="/root/parent">
  <xsl:for-each select="table">
    <xsl:for-each-group select="//type" group-by="@t">
       <xsl:copy-of select="current-group( )[1]"/>
    </xsl:for-each-group>
  </xsl:for-each>
<xsl-template>

但是我没有输出!我相信有些缺陷。

使用不同的值():

<xsl:for-each select="distinct-values(type/@t)">
<xsl:sort/>
<xsl:value-of select="."/> <xsl:call-template name="newline"/>
</xsl:for-each>

仍然没有想要的输出。

预期的输出是:

enumone
int
string
enumtwo
float
enumthree

感谢这方面的任何帮助。

4

2 回答 2

2

好吧,输入样本不是格式良好的 XML,但如果你真的只想要所有元素的不同t属性值,那么做type

<xsl:template match="/">
  <xsl:value-of select="distinct-values(//type/@t)" separator="&#10;"/>
</xsl:template>

XSLT 2.0 就足够了。

如果您还想对不同的值进行排序,则执行

<xsl:template match="/">
  <xsl:value-of separator="&#10;">
    <xsl:perform-sort select="distinct-values(//type/@t)">
       <xsl:sort select="."/>
    </xsl:perform-sort>
  </xsl:value-of>
</xsl:template>

举一个完整的例子,输入为

<root>
  <foo>
    <type t="int"/>
  </foo>
  <bar>
    <type t="enum"/>
  </bar>
  <foobar>
     <foo>
        <type t="enum">
           <x/>
        </type>
     </foo>
   </foobar>
   <foo>
      <type t="string"/>
   </foo>
</root>

样式表

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text"/>

<xsl:template match="/">
  <xsl:value-of separator="&#10;">
    <xsl:perform-sort select="distinct-values(//type/@t)">
       <xsl:sort select="."/>
    </xsl:perform-sort>
  </xsl:value-of>
</xsl:template>

</xsl:stylesheet>

输出

enum
int
string
于 2012-08-03T09:39:45.107 回答
0

只需将您的代码修改为

<xsl:template match="/">
    <xsl:for-each-group select="//type" group-by="@t">
       <xsl:copy-of select="current-group( )[1]"/>
    </xsl:for-each-group>
</xsl:template>

完整的转变

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:template match="/">
    <xsl:for-each-group select="//type" group-by="@t">
       <xsl:copy-of select="current-group( )[1]"/>
    </xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>

当应用于格式良好的 XML 文档时

<root>
  <foo>
    <type t="int"/>
  </foo>
  <bar>
    <type t="enum"/>
  </bar>
  <foobar>
     <foo>
        <type t="enum">
           <x/>
        </type>
     </foo>
   </foobar>
   <foo>
      <type t="string"/>
   </foo>
</root>

产生正确的结果

<type t="int"/>
<type t="enum"/>
<type t="string"/>
于 2012-08-03T14:37:31.000 回答