繁体   English   中英

XQuery如何过滤节点及其子节点

[英]XQuery how to filter nodes & its child nodes

如何从“ for”中循环的节点中仅选择前2个子节点

例如,我有这个xml,我需要选择合格的“是”人,我只想要他的前2个关联。 我的输出应该是带有过滤节点的相同XML结构。 我知道这对于XSLT来说是简单的任务,但是只是想知道XQuery是否有一种简单的方法。

    <?xml version="1.0" encoding="UTF-8"?>
<Persons>
    <Person>
        <Name>Sam</Name>
        <DOB>12-2-1981</DOB>
        <Qualified>Yes</Qualified>
        <Assosiation>
            <Code>1</Code>
            <Descreption>Assosiatoin1</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>2</Code>
            <Descreption>Assosiatoin2</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>3</Code>
            <Descreption>Assosiatoin3</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>4</Code>
            <Descreption>Assosiatoin4</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>5</Code>
            <Descreption>Assosiatoin5</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>6</Code>
            <Descreption>Assosiatoin6</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>7</Code>
            <Descreption>Assosiatoin7</Descreption>
        </Assosiation>
        <DynamicElement>Unkown</DynamicElement>
    </Person>
    <Person>
        <Name>James</Name>
        <DOB>12-2-1975</DOB>
        <Qualified>No</Qualified>
        <Assosiation>
            <Code>1</Code>
            <Descreption>Assosiatoin1</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>2</Code>
            <Descreption>Assosiatoin2</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>3</Code>
            <Descreption>Assosiatoin3</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>4</Code>
            <Descreption>Assosiatoin7</Descreption>
        </Assosiation>
        <DynamicElement>Unkown</DynamicElement>
    </Person>
    <Person>
        <Name>Jon</Name>
        <DOB>12-2-1983</DOB>
        <Qualified>Yes</Qualified>
        <Assosiation>
            <Code>1</Code>
            <Descreption>Assosiatoin1</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>2</Code>
            <Descreption>Assosiatoin2</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>3</Code>
            <Descreption>Assosiatoin3</Descreption>
        </Assosiation>
        <Assosiation>
            <Code>4</Code>
            <Descreption>Assosiatoin7</Descreption>
        </Assosiation>
        <DynamicElement>Unkown</DynamicElement>
    </Person>
</Persons>

非XQuery Update解决方案:

element Persons {
  for $person in $xml/Persons/Person
  where $person/Qualified = 'Yes'
  return element Person {
    $person/Name,
    $person/DOB,
    $person/Qualified,
    $person/Assosiation[position() = (1,2)],
    $person/DynamicElement
  }
}

如果您希望对其他元素的名称不那么具体:

element Persons {
  for $person in $xml/Persons/Person
  where $person/Qualified = 'Yes'
  return element Person {
    for $element in $person/*
    return
      $element[
        local-name($element) != 'Assosiation' or
        count($element/preceding-sibling::Assosiation) < 2
      ]
  }
}

由于Oracle 11.2.0.3.0,Oracle还支持XQuery Update ,这是在这种情况下使用的正确工具。

XQuery本身不处理XML数据,因此您将需要重建完整的树,而只保留不需要的节点。 使用XQuery Update,您可以修改XML,从而仅删除不需要的节点:

copy $c := .
modify
  for $p in $c//Person[Qualified = "Yes"][position() > 2]
  return delete node $p
return $c

但是,在示例数据中,只有两个<Person />元素,且Qualified设置为Yes,因此不会删除任何内容。 如果您要说的是要使用前两个元素,而仅将Qualified设置为Yes,则必须交换谓词,即$c//Person[position() > 2][Qualified = "Yes"]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM