【问题标题】:XPath multiple validation conditions with multiple XML tags具有多个 XML 标记的 XPath 多个验证条件
【发布时间】:2018-04-11 06:55:13
【问题描述】:

我正在尝试编写一个 XPath 验证表达式来检查下面显示的 XML 表单的正确性。我想验证一下:

  • 如果是OperationType = 1,单个User 节点中的所有字段都已填充
  • OperationType = 2 的情况下,各个User 节点中的Login 字段至少被填充

我想出了以下表达式,但它仅在存在单个 User 节点时才有效:

//wnio:Login!=''
and (//wnio:FirstName!='' or //wnio:OperationType!='1')
and (//wnio:LastName!='' or //wnio:OperationType!='1') 
and (//wnio:Email!='' or //wnio:OperationType!='1')

但是,如果这些字段在单独的 User 标记中不为空,则可以肯定地验证文档。

我很想知道是否可以在类似于以下的结构中验证这些条件。对于如何处理此问题的任何建议,我将不胜感激。

<wnio:Document>
    <wnio:Content>
        <wnio:SubmittedUsers>
            <wnio:User>
                <wnio:OperationType>1</wnio:OperationType>
                <wnio:FirstName>Adam</wnio:FirstName>
                <wnio:Login>adamnowak</wnio:Login>
                <wnio:Email>adamnowak@example.com</wnio:Email>
                <wnio:LastName>Nowak</wnio:LastName>
            </wnio:User>
            <wnio:User>
                <wnio:OperationType>2</wnio:OperationType>
                <wnio:FirstName/>
                <wnio:Login>testlogin</wnio:Login>
                <wnio:Email/>
                <wnio:LastName/>
            </wnio:User>
            <wnio:User>
                <wnio:OperationType>1</wnio:OperationType>
                <wnio:FirstName>John</wnio:FirstName>
                <wnio:Login>johnsmith</wnio:Login>
                <wnio:Email>johnsmith@example.com</wnio:Email>
                <wnio:LastName>Smith</wnio:LastName>
            </wnio:User>
        </wnio:SubmittedUsers>
        <wnio:AuthorityType>1</wnio:AuthorityType>
    </wnio:Content>
</wnio:Document>

【问题讨论】:

  • 你有没有尝试过类似的东西:/wnio:Document/wnio:Content/wnio:SubmittedUsers/wnio:User[(wnio:OperationType = '1' and wnio:FirstName != '' and wnio:Login != '' and wnio:Email != '' and wnio:LastName != '') or (wnio:OperationType = '2' and wnio:Login != '')]
  • @GGO - 这工作正常!非常感谢您的帮助!

标签: xml validation xpath


【解决方案1】:

你可以使用:

/wnio:Document/wnio:Content/wnio:SubmittedUsers/wnio:User
[(w‌​nio:OperationType = '1' and wnio:FirstName != '' and wnio:Login != '' and wnio:Email != '' and wnio:LastName != '') 
or (wnio:OperationType = '2' and wnio:Login != '')]

【讨论】:

    【解决方案2】:

    选择不满足您的任何条件的wnio:User 元素,查看生成的节点集是否为空。

    //wnio:User[not(
      (
        wnio:OperationType = '1' 
        and wnio:Login > '' 
        and wnio:FirstName > '' 
        and wnio:LastName > ''
      )
      or (
        wnio:OperationType = '2' 
        and wnio:Login > '' 
      )
    )]
    

    如果这不选择任何内容,则所有 wnio:User 元素都满足您的规则。为了更加确定,您可以添加一个条件来选择具有无效OperationType 的元素。

    查看XML Schema(或Relax NG),因为这些是为了在 XML 中强制执行语义规则。

    【讨论】:

    • 不幸的是,它允许传递一个包含所有空字段和字段的文档,这些字段在每列的单独行中填充。
    • 是的,我检查了几次,最终在删除第一行中的not 后它工作了。谢谢!
    • 但是现在测试不再起作用了。如果您想验证(验证)您的 XML,那么您必须选择与您的规则不匹配的元素,而不是匹配的元素。
    • 好吧,我检查了更多文档组合,但不幸的是,它们都不起作用。以this XML 为例。我使用了您的 XPath,它返回了所有 4 个节点(在 Notepad++ 中),而在 freeformatter.com 上只有错误的一个。但是,我使用的系统中的评估器 (ePUAP) 没有检测到错误。 3 种工具对相同的输入给出不同的结果似乎很奇怪。
    • 最后我用这样的表达式解决了这个问题:not(/wnio:Dokument/wnio:TrescDokumentu/wnio:SubmittedUsers/wnio:User[(wnio:OperationType='1' and wnio:Login = '') or (wnio:OperationType='1' and wnio:FirstName= '') or (wnio:OperationType='1' and wnio:LastName= '') or (wnio:OperationType='1' and wnio:Email= '') or (wnio:OperationType='2' and wnio:Login= '')])
    【解决方案3】:

    在我使用的系统 (ePUAP) 中,正确的表达式是:

    not(/wnio:Dokument/wnio:TrescDokumentu/wnio:SubmittedUsers/wnio:User[
    (wnio:OperationType='1' and wnio:Login = '') 
    or (wnio:OperationType='1' and wnio:FirstName= '') 
    or (wnio:OperationType='1' and wnio:LastName= '') 
    or (wnio:OperationType='1' and wnio:Email= '') 
    or (wnio:OperationType='2' and wnio:Login= '')
    ])
    

    可以简化为:

    not(/wnio:Dokument/wnio:TrescDokumentu/wnio:SubmittedUsers/wnio:User[
    ((wnio:OperationType='1' 
      and (wnio:Login = '' or wnio:FirstName= '' or wnio:LastName= '' or  wnio:Email= '')) 
    or (wnio:OperationType='2' and wnio:Login= ''))
    ])
    

    上面的表达式返回两个条件的验证错误:

    • 如果是OperationType = 1,单个User 节点中的所有字段都必须是 填满
    • OperationType = 2 的情况下至少有Login 字段内 必须填写相应的User 节点

    【讨论】:

    • 你的简化看起来很像我的解决方案。 :)
    • @Tomalak 你是对的 - 你的解决方案帮助了我很多,我真的很感激。主要区别在于我必须否定所有 XPath 表达式。
    猜你喜欢
    • 1970-01-01
    • 2012-05-02
    • 2015-07-25
    • 2022-01-03
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多