3

使用下面的 XML,是否可以使用 XPath 表达式选择本地项目元素,其中具有相同代码的区域项目的金额在本地项目金额的 5% 以内?在此示例中,将选择本地项目 4。

<?xml version="1.0" encoding="UTF-8"?>

<Inventory> 
  <Local> 
    <Item> 
      <Code>1</Code>  
      <Amount>10000</Amount> 
    </Item>  
    <Item> 
      <Code>2</Code>  
      <Amount>20000</Amount> 
    </Item>  
    <Item> 
      <Code>3</Code>  
      <Amount>30000</Amount> 
    </Item>  
    <Item> 
      <Code>4</Code>  
      <Amount>40000</Amount> 
    </Item> 
  </Local>  
  <Regional> 
    <Item> 
      <Code>2</Code>  
      <Amount>100</Amount> 
    </Item>  
    <Item> 
      <Code>4</Code>  
      <Amount>39900</Amount> 
    </Item> 
  </Regional> 
</Inventory>

到目前为止,我只能使用下面的表达式选择具有相同代码的本地项目,该表达式返回两个元素,但我似乎无法弄清楚如何将两个元素乘以 0.95,因为将“/Amount * 0.95”添加到这个表达式的结尾使它只返回第一个项目的数量乘以 0.95。

/Inventory/Local/Item[Code=/Inventory/Regional/Item/Code]
4

3 回答 3

0

你可以试试xquery

XQuery

for $x in doc("input.xml")//Local/Item
let $y:=doc("input.xml")//Regional/Item[Code=$x/Code]
where $y/Amount*0.95<=$x/Amount and $x/Amount<=$y/Amount*1.05
return $x

在 shell 中测试

$ zorba -q 'for $x in doc("input.xml")//Local/Item let $y:=doc("input.xml")//Regional/Item[Code=$x/Code] where $y/Amount*0.95<=$x/Amount and $x/Amount<=$y/Amount*1.05 return $x'

输出

<?xml version="1.0" encoding="UTF-8"?>
<Item> 
      <Code>4</Code>  
      <Amount>40000</Amount> 
</Item>
于 2013-03-15T01:01:58.613 回答
0

我发现这个问题很有趣,过去一个小时一直在尝试解决它,

这是使用XPATH 2.0的解决方案:

for $x  in   /Inventory/Local/Item[Code=/Inventory/Regional/Item/Code],
    $y   in   /Inventory/Regional/Item[Code = $x/code]
      return  $x[Amount div 20 <= $y/Amount ]

很确定这不能使用XPath 1.0 表达式来完成。

于 2013-03-15T01:04:17.903 回答
0

XQuery 不需要指定所需的选择

这是一个正确、更短且更高效的 XPath 2.0 表达式

for $locItem in /*/Local/*,
    $locAmount in $locItem/Amount,
    $fivePercent in $locAmount*0.05,
    $regItem in
    /*/Regional/Item
         [Code eq $locItem/Code
        and
         abs(Amount -$locAmount) le $fivePercent
         ]
 return $locItem

基于 XSLT 2.0 的验证:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:sequence select=
   "for $locItem in /*/Local/*,
        $locAmount in $locItem/Amount,
        $fivePercent in $locAmount*0.05,
        $regItem in
        /*/Regional/Item
             [Code eq $locItem/Code
            and
             abs(Amount -$locAmount) le $fivePercent
             ]
     return $locItem"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<Inventory>
  <Local>
    <Item>
      <Code>1</Code>
      <Amount>10000</Amount>
    </Item>
    <Item>
      <Code>2</Code>
      <Amount>20000</Amount>
    </Item>
    <Item>
      <Code>3</Code>
      <Amount>30000</Amount>
    </Item>
    <Item>
      <Code>4</Code>
      <Amount>40000</Amount>
    </Item>
  </Local>
  <Regional>
    <Item>
      <Code>2</Code>
      <Amount>100</Amount>
    </Item>
    <Item>
      <Code>4</Code>
      <Amount>39900</Amount>
    </Item>
  </Regional>
</Inventory>

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

<Item>
    <Code>4</Code>
    <Amount>40000</Amount>
</Item>
于 2013-03-15T03:46:28.880 回答