2013-03-06 61 views
1

比如我有一个xml:的XPath/XSLT等检查多个值

<?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在这个例子中的所有值结果是假的,因为DbResponse/ResultSet/Row/Cell[@name="WEANR"]没有0171688405

回答

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

+0

谢谢!你能解释一下这是如何工作的吗? – VextoR 2013-03-07 05:31:56

+1

@VextoR,在这个答案中,我提出了一个双重否定定律的链接。因此,集合中的所有项都具有属性X,如果没有不具有此属性X的项目。现在,只需用'/ */ProcessPurchaseOrder/*/*/ID'和'property X'与'=/*/DbResponse/*/*/Cell [@ name ='WEANR']' – 2013-03-07 05:41:01

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

不是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) 

你也可以通过编写

混合本例中的“=”运算符的隐性量化的明确量化0
every $id in //ID satisfies ($id = //Cell) 

这可能是我的选择。