1

例如我有一个xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<TemporaryRoot>
    <ProcessPurchaseOrder>
        <DocumentReference>
            <AlternateDocumentID>
                <ID>0171688401</ID>
            </AlternateDocumentID>
            <AlternateDocumentID>
                <ID>0171688404</ID>
            </AlternateDocumentID>
            <AlternateDocumentID>
                <ID>0171688405</ID>
            </AlternateDocumentID>
        </DocumentReference>
    </ProcessPurchaseOrder>
    <DbResponse>
        <ResultSet>
            <Row>
                <Cell name="WEANR" type="VARCHAR2">0171688401</Cell>
            </Row>
            <Row>
                <Cell name="WEANR" type="VARCHAR2">0171688404</Cell>
            </Row>
        </ResultSet>
    </DbResponse>
</TemporaryRoot>

如何编写 xpath 或 xslt 代码来检查是否DbResponse/ResultSet/Row/Cell[@name="WEANR"]包含来自AlternateDocumentID/ID's 的所有值

在这个例子中结果是假的,因为DbResponse/ResultSet/Row/Cell[@name="WEANR"]没有0171688405价值

4

3 回答 3

2

您可以使用 XPath 2.0 构造,而不是 Dimitre 的使用not(X[not(. = Y)]),这对于那些没有接受过数学训练或没有直观掌握符号逻辑的人来说有点难以理解

every $x in X satisfies (some $y in Y satisfies $x eq $y)

具体来说

every $id in //ID satisfies (some $cell in //Cell satisfies $id eq $cell)

您还可以通过编写将此示例的显式量化与“=”运算符的隐式量化混合在一起

every $id in //ID satisfies ($id = //Cell)

这可能是我的选择。

于 2013-03-07T10:58:06.317 回答
1

作为 XPath 解决方案,您可以检查与节点Row/Cell匹配的所有AlternateDocumentID/ID节点,然后将其与总节点进行比较:

count(//DbResponse/ResultSet/Row[Cell/@name='WEANR' and  //AlternateDocumentID/ID/text() = Cell/text()]) = count(//AlternateDocumentID/ID)

对于 XSLT 解决方案,这里有一个很好的示例问题,说明如何做到这一点。

于 2013-03-06T13:56:55.713 回答
1

使用这个单一的 XPath 1.0 表达式

not(/*/ProcessPurchaseOrder
                /*/*/ID[not(. = /*/DbResponse/*/*/Cell[@name='WEANR'])])

基于 XSLT 的验证

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
     <xsl:copy-of select=
     "not(/*/ProcessPurchaseOrder
                /*/*/ID[not(. = /*/DbResponse/*/*/Cell[@name='WEANR'])])"/>
 </xsl:template>
</xsl:stylesheet>

当对提供的 XML 文档应用此转换时:

<TemporaryRoot>
    <ProcessPurchaseOrder>
        <DocumentReference>
            <AlternateDocumentID>
                <ID>0171688401</ID>
            </AlternateDocumentID>
            <AlternateDocumentID>
                <ID>0171688404</ID>
            </AlternateDocumentID>
            <AlternateDocumentID>
                <ID>0171688405</ID>
            </AlternateDocumentID>
        </DocumentReference>
    </ProcessPurchaseOrder>
    <DbResponse>
        <ResultSet>
            <Row>
                <Cell name="WEANR" type="VARCHAR2">0171688401</Cell>
            </Row>
            <Row>
                <Cell name="WEANR" type="VARCHAR2">0171688404</Cell>
            </Row>
        </ResultSet>
    </DbResponse>
</TemporaryRoot>

计算 XPath 表达式并将结果复制到输出:

false

当我们将文档更改为此:

<TemporaryRoot>
    <ProcessPurchaseOrder>
        <DocumentReference>
            <AlternateDocumentID>
                <ID>0171688401</ID>
            </AlternateDocumentID>
            <AlternateDocumentID>
                <ID>0171688404</ID>
            </AlternateDocumentID>
        </DocumentReference>
    </ProcessPurchaseOrder>
    <DbResponse>
        <ResultSet>
            <Row>
                <Cell name="WEANR" type="VARCHAR2">0171688401</Cell>
            </Row>
            <Row>
                <Cell name="WEANR" type="VARCHAR2">0171688404</Cell>
            </Row>
        </ResultSet>
    </DbResponse>
</TemporaryRoot>

应用于此文档的转换再次产生正确的结果:

true

说明

正确使用双重否定法

于 2013-03-07T04:46:28.407 回答