xpath / xslt等于检查多个值

时间:2013-03-06 13:48:09

标签: xml xslt xpath xslt-2.0

例如我有一个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的所有值

此示例中的

结果为false,因为DbResponse/ResultSet/Row/Cell[@name="WEANR"]没有0171688405

3 个答案:

答案 0 :(得分:2)

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

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)

这可能是我的选择。

答案 1 :(得分:1)

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

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

对于XSLT解决方案,here's a good example question了解如何执行此操作。

答案 2 :(得分: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

<强>解释

正确使用 Double-Negation Law