简体   繁体   中英

XSLT 1.0 not(contains in for-each

I want to include this:

not(contains(country/product/@genericname, 'Color Purple'))

in this for-each

<xsl:for-each select="country[@name = 'GB']/product[@category = 'inkjet' and contains(@classification, 'consumer') or contains(@classification, 'businessinkjet')]">

I tried this:

<xsl:for-each select="not(contains(country/product/@genericname, 'Stylus Pro')) and country[@name = $country]/product[@category = 'inkjet' and contains(@classification, 'consumer') or contains(@classification, 'businessinkjet')]">

But, I get this error: The value is not a node-set . I don't see the syntax error.

Processor: Saxon6.5.5

@michael.hor257k

I adapted your snippet, look hier the right for-each with params of mine.

<xsl:param name="country">GB</xsl:param>
<xsl:for-each select="country[@name = $country]/product[@category = 'inkjet' and contains(@classification, 'consumer') or contains(@classification, 'businessinkjet')] [not(contains(country/product/@genericname, 'Stylus Pro'))]">

XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<countries>
    <country name="GB">
        <product genericname="Yellow line" id="12345" />
        <product genericname="Red line" id="6789" type="device" />
        <product genericname="This is Stylus Pro" id="256464" />
    </country>
</countries>

EDIT

Here is the right way, thanks, is was the wrong path.

<xsl:for-each select="country[@name = 'GB']/product[@category = 'inkjet' and contains(@classification, 'consumer') or contains(@classification, 'businessinkjet')] [not(contains(**@genericname**, 'Stylus Pro'))]">

not country/product/@genericname

Thanks

not(contains()) needs to be in a predicate (inside square brackets). Outside of the predicate/s, you need to have a path leading to a node. Post an example of your XML code for a more specific answer.

I am guessing this may be what you want:

<xsl:for-each select="country[@name = 'GB']/product[@category = 'inkjet' and contains(@classification, 'consumer') or contains(@classification, 'businessinkjet')] [not(contains(@genericname, 'Color Purple'))]">

Note that the path points to product , and the predicates limit the classes of products to be included in the selection.


Edit:

XSLT is very context-sensitive.

[not(contains(@genericname, 'Stylus Pro'))]

is very different from:

[not(contains(country/product/@genericname, 'Stylus Pro'))] 

The first one looks at the genericname attribute of the current node . In the context of:

select="country[...]/product[...]"

the current node is product .

The second one looks at the genericname attribute of a node named product that is a child of country that is a child of the current node. This attribute does not exist - so of course it does not contain the search string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM