xpath/xslt等于检查多个值

时间:2022-11-05 13:08:48

For example I have an xml:

例如,我有一个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>

How to write xpath or xslt code to check if DbResponse/ResultSet/Row/Cell[@name="WEANR"] contain all values from AlternateDocumentID/ID's

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

in this example result is false, because DbResponse/ResultSet/Row/Cell[@name="WEANR"] doesn't have 0171688405 value

在这个示例中,结果为false,因为DbResponse/ResultSet/Row/Cell[@name="WEANR"]没有0171688405值

3 个解决方案

#1


1  

Use this single XPath 1.0 expression:

使用这个XPath 1.0表达式:

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

XSLT - based verification:

基于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>

When this transformation is applied against the provided XML document:

当对所提供的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>

the XPath expression is evaluated and the result is copied to the output:

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

false

When we change the document to this:

当我们将文件改为:

<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>

the transformation applied on this document again produces the correct result:

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

true

Explanation:

解释:

Proper use of the Double-Negation Law.

正确使用双重否定律。

#2


2  

Rather than Dimitre's use of not(X[not(. = Y)]), which is a little difficult to understand for those without either mathematical training or an intuitive grasp of symbolic logic, you could use the XPath 2.0 construct

而不是Dimitre对not的使用(X[not])。对于那些既没有数学训练,又没有直观的符号逻辑理解的人来说,你可以使用XPath 2.0构造。

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

specifically

具体地说

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

You could also mix the explicit quantification of this example with the implicit quantification of the "=" operator by writing

您还可以将这个示例的显式量化与“=”运算符的隐式量化混合使用

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

which would probably be my choice.

这可能是我的选择。

#3


1  

As an XPath solution, you could check for all nodes in Row/Cell that match the AlternateDocumentID/ID nodes, then compare it to the total nodes:

作为一种XPath解决方案,您可以检查行/单元中与exchangedocumentid /ID节点匹配的所有节点,然后将其与总节点进行比较:

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

For an XSLT solution, here's a good example question for how to do that.

对于XSLT解决方案,这里有一个很好的示例问题。

#1


1  

Use this single XPath 1.0 expression:

使用这个XPath 1.0表达式:

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

XSLT - based verification:

基于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>

When this transformation is applied against the provided XML document:

当对所提供的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>

the XPath expression is evaluated and the result is copied to the output:

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

false

When we change the document to this:

当我们将文件改为:

<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>

the transformation applied on this document again produces the correct result:

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

true

Explanation:

解释:

Proper use of the Double-Negation Law.

正确使用双重否定律。

#2


2  

Rather than Dimitre's use of not(X[not(. = Y)]), which is a little difficult to understand for those without either mathematical training or an intuitive grasp of symbolic logic, you could use the XPath 2.0 construct

而不是Dimitre对not的使用(X[not])。对于那些既没有数学训练,又没有直观的符号逻辑理解的人来说,你可以使用XPath 2.0构造。

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

specifically

具体地说

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

You could also mix the explicit quantification of this example with the implicit quantification of the "=" operator by writing

您还可以将这个示例的显式量化与“=”运算符的隐式量化混合使用

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

which would probably be my choice.

这可能是我的选择。

#3


1  

As an XPath solution, you could check for all nodes in Row/Cell that match the AlternateDocumentID/ID nodes, then compare it to the total nodes:

作为一种XPath解决方案,您可以检查行/单元中与exchangedocumentid /ID节点匹配的所有节点,然后将其与总节点进行比较:

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

For an XSLT solution, here's a good example question for how to do that.

对于XSLT解决方案,这里有一个很好的示例问题。