Вопрос

I have an XML format as follows:

<Items>
  <Item id="1">
  </Item>
  <Item id="2">
  </Item>
  <Item id="1">
  </Item>
  <Item id="3">
  </Item>
</Items>

I am trying to declare an XSLT 2.0 variable that will contain all elements where "id" is unique. If the "id" is NOT unique, only the first instance should be output, such that the variable will store:

<Item id="1">
</Item>
<Item id="2">
</Item>
<Item id="3">
</Item>

The following code will give me all of the unique @id attributes, but NOT their parent (Item):

<xsl:variable name="uniqueItems" select="distinct-values(/Items/Item/@id)"/>

I want to do somelike this:

<xsl:variable name="uniqueItems" select="distinct-values(/Items/Item/@id)/parent::node()"/>

But this is obviously not correct.

Это было полезно?

Решение

Given

<xsl:key name="id" match="Item" use="@id"/>

you could use <xsl:variable name="uniqueItems" select="/Items/Item[not(key('id', @id)[2])]"/>.

Or use for-each-group to find groups of single items:

<xsl:variable name="uniqueItems" as="element(Item)">
  <xsl:for-each-group select="/Items/Item" group-by="@id">
   <xsl:if test="not(current-group()[2])">
    <xsl:sequence select="."/>
   </xsl:if>
  </xsl:for-each-group>
</xsl:variable>

If you want to eliminate duplicates then with

<xsl:variable name="uniqueItems" as="element(Item)">
  <xsl:for-each-group select="/Items/Item" group-by="@id">
   <xsl:sequence select="."/>
  </xsl:for-each-group>
</xsl:variable>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top