AAADad
AAADad

Reputation: 153

XPath: Selecting a node based on another nodes value

I am trying to use a single XPath expression to select a node that has a child node which matches another node in the document.

A match would mean that ALL attributes of the node are the same. So if a node was being compared with several attributes doing individual attribute comparisons would be unmaintainable.

As an example given the following:

<Network>
    <Machines>
        <Machine Name = "MyMachine">
            <Services>
                 <ServiceDetails Description="MyService" Executable="c:\Myservice.exe" DisplayName="My Service" Version="5"/>
            </Services>
        </Machine>
        ...
    </Machines>
    <Services>
        <Service Name = "Service1">
            <ServiceDetails Description="MyService" Executable="c:\Myservice.exe" DisplayName="My Service" Version="5"/>
        </Service>
        ...
    </Services>
</Network>

I want to get the service node from Services based on the ServiceDetails listed under MyMachine.

I thought it would look something like:

//Services/Service[ServiceDetails = //Machines/Machine[@Name='MyMachine']/ServiceDetails]

but it doesn't seem to work. I suspect the '=' operator isn't handling the node comparison correctly. I think there are some XPath 2.0 Methods that might work but I am using .NET 4.0 (System.XML namespace) I do not know if I can use them. If XPath 2.0 methods would help here I would really appreciate an explanation on how to use them in .Net 4.0.

Thanks

Upvotes: 1

Views: 2491

Answers (2)

Yogib
Yogib

Reputation: 55

Try this will validate all attribute values are equal in both the elements then it is true:

/Network[(descendant::ServiceDetails/@Description = /Network//Machine[@Name = "MyMachine"]/Services/ServiceDetails/@Description) and (descendant::ServiceDetails/@Executable = /Network//Machine[@Name = "MyMachine"]/Services/ServiceDetails/@Executable) and (descendant::ServiceDetails/@DisplayName = /Network//Machine[@Name = "MyMachine"]/Services/ServiceDetails/@DisplayName) and (descendant::ServiceDetails/@Version = /Network//Machine[@Name = "MyMachine"]/Services/ServiceDetails/@Version)]

Upvotes: 0

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243449

Use:

/*/Services/Service
            [ServiceDetails/@Description 
            = 
             /*/Machines/Machine[@Name = "MyMachine"]
                          /Services/ServiceDetails/@Description
            ]

Upvotes: 4

Related Questions