I want to use the XSD1.1 assert feature to validate Elements on content level. (To be more precise, I want to check the existence of content-combinations in EDIFACT represented in XML, but that's not the main point...)
To test my XPaths I have constructed the following mini-test-scenario:
XML
<root>
<group>
<elem1>test1</elem1>
<elem2>test2</elem2>
</group>
<group>
<elem1>something1</elem1>
<elem2>something2</elem2>
</group>
<group>
<elem1>other1</elem1>
<elem2>other2</elem2>
</group>
</root>
The requirement is: I want to check, that I have the combination of test1 + test2 string, and the combination of something1 and something2 string. There may be groups like the other1 + other2 group, which can be there, but I don't care about. The order of the three groups here also should have no influence.
The XSD I have to test is:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="group" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="elem1" minOccurs="1">
</xsd:element>
<xsd:element name="elem2" minOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:assert test="(count(./group/elem1/text() = 'test1') > 0
and count(./group/elem2/text() = 'test2') > 0)
and (count(./group/elem1/text() = 'something1') > 0
and count(./group/elem2/text() = 'something2') > 0)"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The interesting bit is:
(count(./group/elem1/text() = 'test1') > 0
and count(./group/elem2/text() = 'test2') > 0)
and (count(./group/elem1/text() = 'something1') > 0
and count(./group/elem2/text() = 'something2') > 0)
or to break it down:
count(./group/elem1/text() = 'test1') > 0
My problem is: The expression (count to be more specific) returns true, even if the strings don't match. Let's say, I test against "test1", but my string is "test":
./group/elem1/text() = 'test1'
in it self works. It returns true or false correctly. But using count on it does not work. (Seems to always return true)
I assume, count is not the right solution here, the thing is, I don't want to test each group on "it is exactly" but after all groups "does this and this specific combination occur at least once" within all the repetitions of the groups.
I am testing this on Saxon 9 EE, but the XPath has the same behavior on other XPath implementations as well.
Any help would be greatly appreciated.
Thank you, e
edit:
After getting this to work with the help of Mads Hansen and Michael Kay (Thank you!) I had one last hurdle to jump:
Consider this case:
<root>
<group>
<elem1>test1</elem1>
<elem2>WRONG</elem2>
</group>
<group>
<elem1>WRONG</elem1>
<elem2>test2</elem2>
</group>
</root>
with this XPath
count(group[elem1/text() = 'test1' and elem2/text() = 'test2']) > 0)
This now leads to the above example being NOT Valid (as I would like to), whilst the original XPath I had validated the above, since it didn't check within .