Kricker James
Kricker James

Reputation: 47

XPath to select XML node without a child node with a certain value?

I have the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<targets>
    <target sanctions-set-id="4387" ssid="5762">
        <individual>
            <identity ssid="5764" main="true">
                <name ssid="27036" name-type="primary-name">
                    <value>SomeName1</value>
                </name>
            </identity>
        </individual>
        <modification modification-type="de-listed" enactment-date="2016-02-29" publication-date="2016-03-01" effective-date="2016-03-01"/>
        <modification modification-type="amended" enactment-date="2015-11-17" publication-date="2015-11-18" effective-date="2015-11-18"/>
        <modification modification-type="amended" enactment-date="2014-11-27" publication-date="2014-11-28" effective-date="2014-11-28"/>
        <modification modification-type="amended" enactment-date="2013-12-18" publication-date="2013-12-19" effective-date="2013-12-20"/>
        <modification modification-type="listed"/>
    </target>
    <target sanctions-set-id="4388" ssid="5763">
        <individual>
            <identity ssid="5765" main="true">
                <name ssid="27037" name-type="primary-name">
                    <value>SomeName2</value>
                </name>
            </identity>
        </individual>
        <modification modification-type="amended" enactment-date="2015-11-17" publication-date="2015-11-18" effective-date="2015-11-18"/>
        <modification modification-type="amended" enactment-date="2014-11-27" publication-date="2014-11-28" effective-date="2014-11-28"/>
        <modification modification-type="amended" enactment-date="2013-12-18" publication-date="2013-12-19" effective-date="2013-12-20"/>
        <modification modification-type="listed"/>
    </target>   
</targets>

I need to select any target node that does not have a child node of modification-type delisted. In other words, my xpath should only return the second target of SomeName2 because there is no delisted modification-type.

This is the closest I've been able to get, but it still selects both.

targets/target[modification[@modification-type != 'de-listed']]

Upvotes: 2

Views: 859

Answers (1)

kjhughes
kjhughes

Reputation: 111726

The reason your XPath is selecting both is because both do have modification elements with @modification-type attribute equal to values other than de-listed. Use not() instead of !=...

This XPath,

//target[not(modification[@modification-type = 'de-listed'])]

will select all target elements with no modification children with modification-type attributes equal to de-listed.

Upvotes: 2

Related Questions