alex
alex

Reputation: 93

How do I get all of the non excluded items in this list using an XPATH?

I have the following xml file:

<items>
    <item>
        <name>Suede Shoe</name>
        <category>Footwear</category>
        <price>£90.00</price>
        <tags>
            <footwear />
            <shoes />
        </tags>
    </item>
    <item>
        <name>Leather Shoe</name>
        <category>footwear</category>
        <price>£90.00</price>
        <tags>
            <footwear />
        </tags>
    </item>
    <item>
        <name>Canvas Shoe</name>
        <category>Footwear</category>
        <price>£90.00</price>
        <tags>
            <footwear exclude="true"/>
            <shoes/>
        </tags>
    </item>
    <item>
        <name>Toecap Shoe</name>
        <category>Footwear</category>
        <price>£90.00</price>
        <tags>
            <footwear exclude="true"/>
        </tags>
    </item>
</items>

I would like to select all of the items that contain one of my selected tags, but not bring back a result if the tag is excluded.

examples:

tags: footwear
returns: 1, 2

tags: shoes
returns 1, 3

tags: footwear|shoes
returns 1,2,3

Any help please?

Before including the 'exclude' requirement this xpath was working:

//tags[implode('|', $tags)]/parent::item

the tag "footwear" that is not excluded.

Upvotes: 1

Views: 108

Answers (2)

user357812
user357812

Reputation:

This XPath 1.0 expression:

/items/item[
   tags/*[
      not(@exclude='true')
   ][
      contains(
         concat('|',$tags,'|'),
         concat('|',name(),'|')
      )
   ]
]

With $tags variable set as 'footwear' string selects:

<item>
    <name>Suede Shoe</name>
    <category>Footwear</category>
    <price>£90.00</price>
    <tags>
        <footwear />
        <shoes />
    </tags>
</item>
<item>
    <name>Leather Shoe</name>
    <category>footwear</category>
    <price>£90.00</price>
    <tags>
        <footwear />
    </tags>
</item>

With $tags variable set as 'shoes' string selects:

<item>
    <name>Suede Shoe</name>
    <category>Footwear</category>
    <price>£90.00</price>
    <tags>
        <footwear />
        <shoes />
    </tags>
</item>
<item>
    <name>Canvas Shoe</name>
    <category>Footwear</category>
    <price>£90.00</price>
    <tags>
        <footwear exclude="true" />
        <shoes />
    </tags>
</item>

With $tags variable set as 'footwear|shoes' string selects:

<item>
    <name>Suede Shoe</name>
    <category>Footwear</category>
    <price>£90.00</price>
    <tags>
        <footwear />
        <shoes />
    </tags>
</item>
<item>
    <name>Leather Shoe</name>
    <category>footwear</category>
    <price>£90.00</price>
    <tags>
        <footwear />
    </tags>
</item>
<item>
    <name>Canvas Shoe</name>
    <category>Footwear</category>
    <price>£90.00</price>
    <tags>
        <footwear exclude="true" />
        <shoes />
    </tags>
</item>

Upvotes: 0

SergeS
SergeS

Reputation: 11779

for the footwear|shoes the XPath may look like

//tags[footwear[not( @exclude='true' )]|shoes[not( @exclude='true' )]]/parent::item

This will show 1,2,3

Upvotes: 1

Related Questions