Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

c# - How do I identify duplicate nodes in XPath 1.0 using an XPathNavigator to evaluate?

I am trying to identify duplicate serial numbers from the following xml using XPath 1.0 and then evaluating it in .Net using an XPathNavigator.

<?xml version="1.0" encoding="utf-16"?>
<Inventory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Items>
        <Item>
            <SerialNumber>1111</SerialNumber>
        </Item>
        <Item>
            <SerialNumber>1112</SerialNumber>
        </Item>
        <Item>
            <SerialNumber>1112</SerialNumber>
        </Item>
    </Items>
</Inventory>

I tried to do this by evaluating this

//Items/Item/SerialNumber

expression in a custom XSLT Context Function (implementing IXsltContextFunction like this MSDN example) in .Net but the Invoke function gets called one result at a time so I have no visibility of the other results to find duplicates.

1) Is there a way of doing this using a single XPath 1.0 expression?

OR

2) Is there a way of passing in an array of elements into a single Invoke call of the custom XSLT Context Function class? I'm working in VB.Net but am happy with any C# examples anyone can share.

Thanks,

Gavin

Edit

Thanks to O R Mapper and Dimitre for their responses. I initially accepted O R Mapper's response since it did do what I asked. I've since accepted Dimitre's answer since I like that it provides a distinct list of values. Both responses very helpful though!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm going to answer 1), so 2) should not matter any more:

You can use the preceding-sibling axis on your <Item> elements to find any preceding <Item> elements with the same serial number.

Try this (written so that it returns only the serial numbers themselves rather than elements - if this is not quite what you want, and you don't know how to change the result, let me know):

/Inventory/Items/Item/SerialNumber/node()[.=../../preceding-sibling::Item/SerialNumber/node()]

For your sample document, it returns

1112

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...