开发者

Selecting specific and unique attributes with XPATH

开发者 https://www.devze.com 2023-03-30 15:23 出处:网络
I\'m trying to execute an XPATH query that will allow me to select nodes based on two criteria. First I need nodes that contain a unique attribute value and second I need nodes that contain a specifi

I'm trying to execute an XPATH query that will allow me to select nodes based on two criteria.

First I need nodes that contain a unique attribute value and second I need nodes that contain a specific attribute value.

For example:

<rows>
    <row value="0" id="130"/>
    <row value="1" id="130"/>
    <row value="2" id="130"/>
    <row value="0" id="131"/>
    <row value="1" id="131"/>
    <row value="1" id="131"/>
    <row value="2" id="131"/>
    <row value="0" id="132"/>
    <row value="1" id="132"/>
    <row value="2" id="132"/>
</rows>

In this scenario I'd want all n开发者_如何学Codes that contain unique 'values' but only if they also have id="131". I would also want the second value='1' node removed. I would expect this result:

<row value="0" id="131"/>
<row value="1" id="131"/>
<row value="2" id="131"/>

Is this possible with a single XPATH query?

Thanks.


Yes, but it's not pretty. There is probably a better way, but here it goes:

/rows/row[@id='131'][(not(preceding-sibling::row[@id='131']) or not(following-sibling::row[@id='131'])) or 
                       preceding-sibling::row[@id='131']/@value != @value and 
                       following-sibling::row[@id='131']/@value != @value]

Here's an example using this on a slightly more complicated version of your input XML. (I added another <row value="1" id="131"/> to show that it only returns unique results.)

Input XML:

<rows>
  <row value="0" id="130"/>
  <row value="0" id="131"/>
  <row value="0" id="132"/>
  <row value="1" id="130"/>
  <row value="1" id="131"/>
  <row value="1" id="132"/>
  <row value="2" id="130"/>
  <row value="2" id="131"/>
  <row value="2" id="132"/>
  <row value="1" id="131"/>
</rows>

Results:

<row value="0" id="131"/>
<row value="1" id="131"/>
<row value="2" id="131"/>


Sure, you can use the <xsl:key> element and the key() function. Construct a key that is the combination of the @value and @id attributes of a <row> element, and select only those 'key sets' that contain one node and whose @id attribute is equal to '131' (or whatever).

<xsl:key name="id-key" match="row" use="concat(@value, '-', @id)" />

<xsl:template
    match="row[count(key('id-key', concat(@value, '-', @id))) = 1 and @id='131']">
    <xsl:copy-of select="." />
</xsl:template>

Fun, isn't it?

Read more about it here: http://www.jenitennison.com/xslt/grouping/muenchian.html

EDIT: Sorry, I just realized you needed an XPATH query. Note to self: read the questions more carefully. However, the answer could still be useful, so I'll leave it.

0

精彩评论

暂无评论...
验证码 换一张
取 消