【问题标题】:Nested XPath Query嵌套 XPath 查询
【发布时间】:2020-03-12 02:33:47
【问题描述】:

是的。会计:|

我有一组会计分录;它们成对出现——1 个借方和 1 个贷方。这两个条目共享相同的<SequenceID>。如果其中一个条目引用帐户 1111,我想要两个条目。

我正在使用的(非工作)查询(我大致基于 [XPath. Select nodes based on an other, related node)是:

GLPostings/GLTransaction[GLPostings/GLTransaction[AccountCode = '1111']/SequenceID = SequenceID]

但我收到“返回空序列”。

如果我测试部分查询:GLPostings/GLTransaction[AccountCode = '1111']/SequenceID 我会按预期获得多个 SequenceID。那么...如何将这些多个 SequenceID 转换为我所追求的节点集?

这是一些测试数据:

<?xml version="1.0" encoding="UTF-8"?>
<GLPostings>
   <GLTransaction RowNumber="1">
      <CRDR>Dr</CRDR>
      <SequenceID>616</SequenceID>
      <AccountCode>5531</AccountCode>
   </GLTransaction>
   <GLTransaction RowNumber="2">
      <CRDR>Cr</CRDR>
      <SequenceID>616</SequenceID>
      <AccountCode>2118</AccountCode>
   </GLTransaction>
   <GLTransaction RowNumber="3">
      <CRDR>Dr</CRDR>
      <SequenceID>617</SequenceID>
      <AccountCode>1111</AccountCode>
   </GLTransaction>
   <GLTransaction RowNumber="4">
      <CRDR>Cr</CRDR>
      <SequenceID>617</SequenceID>
      <AccountCode>1234</AccountCode>
   </GLTransaction>
   <GLTransaction RowNumber="5">
      <CRDR>Dr</CRDR>
      <SequenceID>618</SequenceID>
      <AccountCode>1231</AccountCode>
   </GLTransaction>
   <GLTransaction RowNumber="6">
      <CRDR>Cr</CRDR>
      <SequenceID>618</SequenceID>
      <AccountCode>1231</AccountCode>
   </GLTransaction>
   <GLTransaction RowNumber="7">
      <CRDR>Dr</CRDR>
      <SequenceID>619</SequenceID>
      <AccountCode>2341</AccountCode>
   </GLTransaction>
   <GLTransaction RowNumber="8">
      <CRDR>Cr</CRDR>
      <SequenceID>619</SequenceID>
      <AccountCode>1111</AccountCode>
   </GLTransaction>
</GLPostings>

我想得到的是:

   <GLTransaction RowNumber="3">
      <CRDR>Dr</CRDR>
      <SequenceID>617</SequenceID>
      <AccountCode>1111</AccountCode>
   </GLTransaction>
   <GLTransaction RowNumber="4">
      <CRDR>Cr</CRDR>
      <SequenceID>617</SequenceID>
      <AccountCode>1234</AccountCode>
   </GLTransaction>
   <GLTransaction RowNumber="7">
      <CRDR>Dr</CRDR>
      <SequenceID>619</SequenceID>
      <AccountCode>2341</AccountCode>
   </GLTransaction>
   <GLTransaction RowNumber="8">
      <CRDR>Cr</CRDR>
      <SequenceID>619</SequenceID>
      <AccountCode>1111</AccountCode>
   </GLTransaction>

非常感谢任何提示。

编辑: 我可以这样解决问题:

<xsl:for-each select="/GLPostings/GLTransaction[AccountCode = 1111']/SequenceID">
    <xsl:variable name="Seq" select="."/>
    <xsl:for-each select="/GLPostings/GLTransaction[SequenceID = $Seq]">
         <xsl:call-template name="output-row">
        </xsl:call-template>
    </xsl:for-each>          
</xsl:for-each>  

但它似乎有点……脏。

【问题讨论】:

    标签: xpath xquery


    【解决方案1】:
    /GLPostings/GLTransaction[AccountCode=1111][SequenceID[.=following::SequenceID or .=preceding::SequenceID]]
    

    将获得 GLTransaction 节点,其 AccountCode 子节点等于 1111,其 SequenceID 子节点等于前面或后面的 SequenceID 节点

    /GLPostings/GLTransaction[SequenceID[.=following::SequenceID[./following-sibling::AccountCode=1111] or .=preceding::SequenceID[./following-sibling::AccountCode=1111]]]
    

    将获得GLTransaction 节点,其SequenceID 子节点等于前面或后面的SequenceID 节点,其AccountCode 后面的兄弟节点等于1111

    将这些 xpath 组合成:

    /GLPostings/GLTransaction[AccountCode=1111][SequenceID[.=following::SequenceID or .=preceding::SequenceID]]|/GLPostings/GLTransaction[SequenceID[.=following::SequenceID[./following-sibling::AccountCode=1111] or .=preceding::SequenceID[./following-sibling::AccountCode=1111]]]
    

    将为您提供 4 个节点(在 xpathtester.com 上测试)

    【讨论】:

    • 感谢 Joel 和 E。您的解决方案将适用于我的情况。 ...但老实说,我很惊讶没有更通用的解决方案来搜索文档节点中的值,然后搜索从文档中任何位置返回的序列派生的值。也许它根本不存在,我被 SQL 宠坏了;)(我在这里感到忘恩负义,因为你给了我我需要的东西,而不是我想要的)。
    • xquery 可以使用键吗?如果是这样,那就更简单了。
    【解决方案2】:

    编辑:重新访问 XPath

    //AccountCode[.="1111"]/parent::*|//AccountCode[following::AccountCode[1]="1111" and following::SequenceID[1]=preceding::SequenceID[1]]/parent::*|//AccountCode[preceding::AccountCode[1]="1111" and preceding::SequenceID[2]=preceding::SequenceID[1]]/parent::*
    

    更安全的选项(如果您没有两个连续的 SequenceID):

    //AccountCode[.="1111"][following::SequenceID[1]=preceding::SequenceID[1]]/parent::*|//AccountCode[.="1111"][preceding::SequenceID[2]=preceding::SequenceID[1]]/parent::*|//AccountCode[following::AccountCode[1]="1111" and following::SequenceID[1]=preceding::SequenceID[1]]/parent::*|//AccountCode[preceding::AccountCode[1]="1111" and preceding::SequenceID[2]=preceding::SequenceID[1]]/parent::*
    

    【讨论】:

    • 非常感谢。像宣传的那样工作。只是为了我自己的启迪,我仍然会对我原来的查询在哪里产生兴趣。
    • "GLTransaction[GLPostings...." 与 XML 结构不对应(GLPostings 位于树的顶部。+ "SequenceID = SequenceID]" :您正在尝试比较一个节点具有相同的节点(相同父节点的子节点)。
    • 对不起,我错了,它不能按我的需要工作。问题是该建议依赖于 1111 帐户节点在其对应的配对节点之前。恐怕我不能依靠。我更改了测试数据以反映这一点,并添加了贷方和借方,以防万一有助于解决方案。
    • 好的。使用更多选项编辑帖子。也检查 Joel M. Lamsen 的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    • 2019-07-18
    相关资源
    最近更新 更多