XSD 中的 X-Path 2.0(断言):"count(//elem/text() = 'test') > 0" 始终为真,即使字符串不匹配
X-Path 2.0 in XSD (assert): "count(//elem/text() = 'test') > 0" always true, even if string does not match
我想使用 XSD1.1 断言功能在内容级别验证元素。
(更准确地说,我想检查 XML 中表示的 EDIFACT 中是否存在内容组合,但这不是重点...)
为了测试我的 XPath,我构建了以下小型测试场景:
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>
要求是:我要检查,我有 test1 + test2 字符串的组合,以及 something1 和 something2 字符串的组合。可能有像 other1 + other2 组这样的组,可以有,但我不在乎。这里三组顺序应该也没有影响。
我要测试的XSD是:
<?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>
有趣的是:
(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)
或分解:
count(./group/elem1/text() = 'test1') > 0
我的问题是:表达式(计数更具体)return为真,即使字符串不匹配。比方说,我针对 "test1" 进行测试,但我的字符串是 "test":
./group/elem1/text() = 'test1'
它自己工作。 return正确或错误。但是对它使用计数是行不通的。 (似乎总是 return 正确)
我假设,在这里计数不是正确的解决方案,问题是,我不想在 "it is exactly" 上测试每个组,但在所有重复的所有组 "does this and this specific combination occur at least once" 之后组。
我正在 Saxon 9 EE 上对此进行测试,但 XPath 在其他 XPath 实现上也具有相同的行为。
如有任何帮助,我们将不胜感激。
谢谢,
e
编辑:
在 Mads Hansen 和 Michael Kay 的帮助下(谢谢!)完成这项工作后,我还有最后一个障碍要跨越:
考虑这个案例:
<root>
<group>
<elem1>test1</elem1>
<elem2>WRONG</elem2>
</group>
<group>
<elem1>WRONG</elem1>
<elem2>test2</elem2>
</group>
</root>
用这个 XPath
count(group[elem1/text() = 'test1' and elem2/text() = 'test2']) > 0)
这现在导致上面的示例无效(正如我所希望的那样),而我已经验证了上面的原始 XPath,因为它没有在 .
内检查
您需要调整 XPath 以过滤您要查找的项目,然后统计剩余的项目。您当前的表达式正在评估 group/elem1/text()
节点中的任何一个是否等于 test1
,这将是 true()
或 false()
,然后您正在计算布尔值。
使用谓词测试 text()
值并计算满足条件的数量:
count(./group/elem1/text()[.='test1'])
答案:
<?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'
and elem2/text() = 'test2']) > 0)
and (count(group[elem1/text() = 'something1'
and elem2/text() = 'something2']) > 0 )"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
将验证:
<root>
<group>
<elem1>test1</elem1>
<elem2>test2</elem2>
</group>
<group>
<elem1>test1</elem1>
<elem2>test4</elem2>
</group>
<group>
<elem1>something1</elem1>
<elem2>something2</elem2>
</group>
<group>
<elem1>other1</elem1>
<elem2>other2</elem2>
</group>
</root>
我想使用 XSD1.1 断言功能在内容级别验证元素。 (更准确地说,我想检查 XML 中表示的 EDIFACT 中是否存在内容组合,但这不是重点...)
为了测试我的 XPath,我构建了以下小型测试场景:
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>
要求是:我要检查,我有 test1 + test2 字符串的组合,以及 something1 和 something2 字符串的组合。可能有像 other1 + other2 组这样的组,可以有,但我不在乎。这里三组顺序应该也没有影响。
我要测试的XSD是:
<?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>
有趣的是:
(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)
或分解:
count(./group/elem1/text() = 'test1') > 0
我的问题是:表达式(计数更具体)return为真,即使字符串不匹配。比方说,我针对 "test1" 进行测试,但我的字符串是 "test":
./group/elem1/text() = 'test1'
它自己工作。 return正确或错误。但是对它使用计数是行不通的。 (似乎总是 return 正确)
我假设,在这里计数不是正确的解决方案,问题是,我不想在 "it is exactly" 上测试每个组,但在所有重复的所有组 "does this and this specific combination occur at least once" 之后组。
我正在 Saxon 9 EE 上对此进行测试,但 XPath 在其他 XPath 实现上也具有相同的行为。
如有任何帮助,我们将不胜感激。
谢谢, e
编辑:
在 Mads Hansen 和 Michael Kay 的帮助下(谢谢!)完成这项工作后,我还有最后一个障碍要跨越:
考虑这个案例:
<root>
<group>
<elem1>test1</elem1>
<elem2>WRONG</elem2>
</group>
<group>
<elem1>WRONG</elem1>
<elem2>test2</elem2>
</group>
</root>
用这个 XPath
count(group[elem1/text() = 'test1' and elem2/text() = 'test2']) > 0)
这现在导致上面的示例无效(正如我所希望的那样),而我已经验证了上面的原始 XPath,因为它没有在 .
内检查您需要调整 XPath 以过滤您要查找的项目,然后统计剩余的项目。您当前的表达式正在评估 group/elem1/text()
节点中的任何一个是否等于 test1
,这将是 true()
或 false()
,然后您正在计算布尔值。
使用谓词测试 text()
值并计算满足条件的数量:
count(./group/elem1/text()[.='test1'])
答案:
<?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'
and elem2/text() = 'test2']) > 0)
and (count(group[elem1/text() = 'something1'
and elem2/text() = 'something2']) > 0 )"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
将验证:
<root>
<group>
<elem1>test1</elem1>
<elem2>test2</elem2>
</group>
<group>
<elem1>test1</elem1>
<elem2>test4</elem2>
</group>
<group>
<elem1>something1</elem1>
<elem2>something2</elem2>
</group>
<group>
<elem1>other1</elem1>
<elem2>other2</elem2>
</group>
</root>