0

我有一个看起来像这样的 xml

<Details>
  <UserResource>
    <ResourceGroup>AJD-IPSP1</ResourceGroup>
    <ResourceType>master</ResourceType>
    <Access>r</Access>
    <UseSOAPFault>soap </UseSOAPFault>
  </UserResource>
  <UserResource>
    <ResourceGroup>AJD-VME1</ResourceGroup>
    <ResourceType>trx</ResourceType>
    <Access>r</Access>
    <UseSOAPFault>soap </UseSOAPFault>
  </UserResource>
  <UserResource>
    <ResourceGroup>AJD-VME10</ResourceGroup>
    <ResourceType>trx</ResourceType>
    <Access>r</Access>
    <UseSOAPFault>soap </UseSOAPFault>
  </UserResource>
  <UserResource>
    <ResourceGroup>AJD-VME11</ResourceGroup>
    <ResourceType>trx</ResourceType>
    <Access>r</Access>
    <UseSOAPFault>soap </UseSOAPFault>
  </UserResource>
</Details>

我想要实现的是:

/Details/UserResource[ResourceGroup="AJD-VME10" or ResourceGroup="AJD-VME1"]

结果应该是

  <UserResource>
    <ResourceGroup>AJD-VME1</ResourceGroup>
    <ResourceType>trx</ResourceType>
    <Access>r</Access>
    <UseSOAPFault>soap </UseSOAPFault>
  </UserResource>
  <UserResource>
    <ResourceGroup>AJD-VME10</ResourceGroup>
    <ResourceType>trx</ResourceType>
    <Access>r</Access>
    <UseSOAPFault>soap </UseSOAPFault>
  </UserResource>

我该怎么做这个xpath?

我想只使用一个 xpath 来做这个。

4

3 回答 3

0

你说你的 DB2 查询是

SELECT SECTIONTITLE, VMETE.COALESCE_XML( 
       XMLQUERY(
         '$c/Details/UserResource
          [ResourceGroup="AJD-VME10" 
          or ResourceGroup="AJD-VME1"]' 
          passing i.SECTIONCONTENT as "c" ), 
       i.SECTIONCONTENT) 
       as SECTIONCONTENT 
  FROM IPSP_CONFIGURATION i 
 WHERE IPSPID='AJD-IPSP1' 
   AND EFFECTIVETO='9999-12-31-23.59.59' 

正如其他人已经观察到的,这里的 XPath 在语法和语义上都是正确的;我倾向于怀疑 SQL/XQuery 接口可能出现的问题:在 XQuery 评估环境中,$c将绑定到元素的元素节点Details还是以该元素作为其子元素的文档节点?这种事情很容易出错,但很容易解决。

但是然后您说该表单“不起作用。但是如果我将 [ResourceGroup="AJD-VME10" 或 ResourceGroup = "AJD-VME1"] 更改为 [ResourceGroup="AJD-VME10"] 它可以工作。

这很奇怪。如果@Natkeeran 建议用括号括起来这两个析取项有效,那么您使用的系统在其解析器中存在错误(这对于 DB2 来说似乎不太可能)。您是否绝对确定按预期工作的查询和不返回任何内容的查询之间的唯一区别是or ResourceGroup="AJD-VME1"从谓词中删除?

于 2013-08-20T22:53:20.083 回答
0

这是一个简单的方法。如果您对 for 循环感到满意,您可以遍历每个 UserResources 并检查 ResourceGroup/text() 是否等于该术语。

    let $x :=
<Details>
  <UserResource>
    <ResourceGroup>AJD-IPSP1</ResourceGroup>
    <ResourceType>master</ResourceType>
    <Access>r</Access>
    <UseSOAPFault>soap </UseSOAPFault>
  </UserResource>
  <UserResource>
    <ResourceGroup>AJD-VME1</ResourceGroup>
    <ResourceType>trx</ResourceType>
    <Access>r</Access>
    <UseSOAPFault>soap </UseSOAPFault>
  </UserResource>
  <UserResource>
    <ResourceGroup>AJD-VME10</ResourceGroup>
    <ResourceType>trx</ResourceType>
    <Access>r</Access>
    <UseSOAPFault>soap </UseSOAPFault>
  </UserResource>
  <UserResource>
    <ResourceGroup>AJD-VME11</ResourceGroup>
    <ResourceType>trx</ResourceType>
    <Access>r</Access>
    <UseSOAPFault>soap </UseSOAPFault>
  </UserResource>
</Details>


return $x/UserResource[ResourceGroup="AJD-VME10" or ResourceGroup="AJD-VME1"]
于 2013-08-20T17:17:02.593 回答
0

这是一个 xsl 解决方案:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Details">
    <xsl:apply-templates select="UserResource" />
</xsl:template>

<xsl:template match="UserResource">
    <xsl:if test="ResourceGroup='AJD-VME10' or ResourceGroup='AJD-VME1'">
        <xsl:element name="{name()}">
            <xsl:copy-of select="*" />
        </xsl:element>
    </xsl:if>

</xsl:template>

于 2013-08-20T17:46:27.393 回答