簡體   English   中英

在xpath謂詞中使用非重復值

[英]Using distinct-values within an xpath predicate

我正在使用XSLT / Xpath 2.0,正在嘗試編寫一個xpath語句,該語句將允許我過濾XML中具有的某些重復節點集。 這是一個示例XML:

<?xml version="1.0" encoding="utf-8"?>
<test>
    <card>
        <TimeCard>1234</TimeCard>
        <tax>HST</tax>
        <adjAmt>-112</adjAmt>
    </card>
    <card>
        <TimeCard>1234</TimeCard>
        <tax>GST</tax>
        <adjAmt>-112</adjAmt>
    </card>
    <card>
        <TimeCard>4321</TimeCard>
        <tax>HST</tax>
        <adjAmt>-50</adjAmt>
    </card>
    <card>
        <TimeCard>4321</TimeCard>
        <tax>GST</tax>
        <adjAmt>-50</adjAmt>
    </card>
    <card>
        <TimeCard>2121</TimeCard>
        <tax>GST</tax>
        <adjAmt>-55</adjAmt>
    </card>
</test>

我需要一個返回“ adjAmt”但每個“ TimeCard”僅返回一次的xpath。 當收取不同類型的稅費時,我的主機系統會為“ adjAmt”創建重復的“卡”條目。 在上面的示例中,我只用它返回-112,-50和-55; 每個“時間卡”一個條目。

我曾嘗試在時間卡元素的許多不同位置使用不重復值,但沒有任何運氣。

任何人對什么最有效有任何建議?

使用

來自 distinct-values()

$ saxon-lint --xpath '
   for $x in distinct-values(/test/card/TimeCard/text())
      return (/test/card/TimeCard[text()=$x]/following-sibling::adjAmt/text())[1]
' file.xml

要么

$ xidel -se '
   for $x in distinct-values(/test/card/TimeCard/text())
      return (/test/card/TimeCard[text()=$x]/following-sibling::adjAmt/text())[1]
' file.xml

group by

$ saxon-lint --no-pi --xquery '
  for $card in test/card group by $tcard := $card/TimeCard
     return $card[1]/adjAmt/data()
' file.xml

要么

$ xidel -s --xquery '
  for $card in test/card group by $tcard := $card/TimeCard
     return $card[1]/adjAmt/data()
' file.xml

歸功於Martin Honnen的最后一個查詢

檢查撒克遜包裝 我自己的項目

在XSLT 2或3中,您可以使用for-each-group group-by來按TimeCard子元素對card元素進行分組,然后返回上下文節點的adjAmt子元素或其編號值,如下所示:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="xs mf"
    version="3.0">

  <xsl:output method="text"/>

  <xsl:function name="mf:group-and-select-first" as="xs:decimal*">
      <xsl:param name="cards" as="element(card)*"/>
      <xsl:for-each-group select="$cards" group-by="TimeCard">
          <xsl:sequence select="xs:decimal(adjAmt)"/>
      </xsl:for-each-group>
  </xsl:function>

  <xsl:template match="/">
     <xsl:value-of select="mf:group-and-select-first(test/card)"/>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bFDb2BP

當您的問題涉及在XPath謂詞中使用該代碼時,我已經將該分組代碼包裝到了函數中,該示例只是在xsl:value-of select表達式的函數調用中調用了該函數,但是您當然也可以使用它如果需要,可在謂詞內部起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM