【问题标题】:How to get a unique value from an XSL transformation?如何从 XSL 转换中获得唯一值?
【发布时间】:2013-03-22 19:17:02
【问题描述】:

我有以下 XML 文件:

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="cars.xsd">
<manufacture id="1">
    <make>Audi</make>
    <classification>
        <list mid="1">
            <type>Sports</type>
        </list>     
        <list  mid="2">
            <type>Compact</type>
        </list>     
        <list  mid="3">
            <type>Compact</type>
        </list> 
    </classification>
</manufacture>
<manufacture id="2">
    <make>bmw</make>
    <classification>
        <list mid="1">
            <type>Sports</type>
        </list>     
        <list  mid="2">
            <type>Luxury</type>
        </list> 
        <list  mid="3">
            <type>Luxury</type>
        </list>                 
    </classification>
</manufacture>
</document>

这是我当前的 XSL 代码:

<?xml version="1.0" encoding="ISO-8859-1"?>

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

 <xsl:output doctype-public="-//WAPFORUM//DTD XHTML Mobile 1.0//EN" 
            doctype-system="http://www.wapforum.org/DTD/xhtml-mobile10.dtd"
 method="xml" version="1.0" 
            omit-xml-declaration="yes" 
            indent="yes" encoding="UTF-8" media-type="text/html"/>

<xsl:template match="/">
<xsl:element name="html">
<xsl:element name="head">           
    <xsl:element name="title">Automotives</xsl:element>
</xsl:element>

<xsl:element name="body">                    
<xsl:element name="ul">
<xsl:attribute name="class">pageitem</xsl:attribute>                    
    <xsl:for-each select="document/manufacture/classification/list">        
        <xsl:element name="li">
        <xsl:attribute name="class">menu</xsl:attribute>        
            <xsl:element name="p">
            <xsl:attribute name="class">name</xsl:attribute>
              <xsl:element name="a">                                
                    <xsl:value-of select="type"/>
                    <xsl:element name="br"/>    
                </xsl:element>      
            </xsl:element>
        </xsl:element>                    
    </xsl:for-each>
</xsl:element>      
</xsl:element>  
</xsl:element>
</xsl:template>
</xsl:stylesheet>

如何在不重复类型的情况下获得以下输出?

Sports
Compact 
Luxury

我是 XSLT 的新手,我尝试过使用 generate-id(),如:Select once from duplicate XML info, display rest, and sort on a field

但这对我不起作用,因为我无法理解 generate-id() 代码。

【问题讨论】:

  • 我认为您正在寻找的术语是 distinct 值,而不是 unique 值。正如蒂姆 C 所说。

标签: xml xpath xslt


【解决方案1】:

您提到了 generate-id,这意味着您可能已经在此处阅读了有关 Muenchian Grouping 的信息,而这确实是您获得不同值所需要的。由于您对 type 元素感兴趣,因此您可以从定义一个键开始,以便通过它们的值轻松查找这些元素。

<xsl:key name="types" match="type" use="." />

现在,要获得不同的元素,您需要遍历所有 type 元素,但您只输出不同的元素。为了告诉它们是不同的,您检查它们是否首先出现在给定值的键中。

这是表达式...

<xsl:apply-templates select="//type[generate-id() = generate-id(key('types', .)[1])]" />

但要将其分解为相应的部分......

key('types', .) - 返回当前值的所有 type 元素

key('types', .)[1] - 返回键中的第一个元素

generate-id(key('types', .)[1]) - 返回该元素的唯一标识符

generate-id() = generate-id(key('types', .)[1]) - 检查当前元素的唯一标识符是否等于键中第一个元素的唯一标识符。

因此,如果它们匹配,它是第一次出现,并且可以输出。

这是完整的 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="text" />
   <xsl:key name="types" match="type" use="." />

   <xsl:template match="/">
      <xsl:apply-templates select="//type[generate-id() = generate-id(key('types', .)[1])]" />
   </xsl:template>

    <xsl:template match="type">
      <xsl:value-of select="concat(., '&#10;')" />
   </xsl:template>
</xsl:stylesheet>

当应用于你的 XML 时,以下是输出

Sports
Compact
Luxury

【讨论】:

  • 非常感谢。这是一个非常详细的解释,易于理解。
猜你喜欢
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 2018-03-19
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多