2

我有以下从 Web 服务中提取并存储在 PL/SQL 中的 XMLTYPE 变量中的 XML 结构:

     <results>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername>
        </return>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername></return>
        <return>
            <customerid>93</customerid>
            <customername>Test2</customername>
        </return>
        <return>
            <customerid>96</customerid>
            <customername>Test3</customername>
        </return>
     </results>

由于我使用的 Web 服务的不灵活性,无法指定只有 1 次出现的 customerid 必须与其对应的值一起显示。考虑到这一点,我如何使用 PL/SQL 解析这个 XML 文档以仅检索每个客户 ID 的第一次出现?

例如,解析上述内容将返回:

       127 Test1
       93 Test2
       96 Test3

我的想法是开始解析 XML 并针对空数组查询客户 ID 是否存在(已打印到屏幕上)。如果没有,则打印客户 ID 匹配的名称以筛选并将客户 ID 添加到数组中。这意味着下一次该 XML 标记将被跳过,它会移动到下一个标记,至少这是我在 PHP 中可以做的,但遗憾的是这一次我必须使用 PL/SQL。

关于在 PL/SQL 中执行此操作的最有效方法的任何想法?

干杯,

杰森

附加:如有必要,我可以更改 XML 文档的结构,因为我自己使用 PL/SQL 动态生成它。

4

1 回答 1

3

将所有节点提取到数据集并选择不同的值:

SQLFiddle

with params as (
  select 
    xmltype('  
     <results>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername>
        </return>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername></return>
        <return>
            <customerid>93</customerid>
            <customername>Test2</customername>
        </return>
        <return>
            <customerid>96</customerid>
            <customername>Test3</customername>
        </return>
     </results>
   ') p_xml 
 from dual
) 
select 
  distinct customer_id, customer_name 
from 
  XMLTable(
    '
      for $i in $doc/results/return     
        return $i
    '
    passing (select p_xml from params) as "doc"
    columns
      customer_id   number         path '//customerid',
      customer_name varchar2(4000) path '//customername'
  )

另一种解析方式:

SQLFiddle

with params as (
  select 
    sys.xmltype('  
     <results>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername>
        </return>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername></return>
        <return>
            <customerid>93</customerid>
            <customername>Test2</customername>
        </return>
        <return>
            <customerid>96</customerid>
            <customername>Test3</customername>
        </return>
     </results>
   ') p_x 
 from dual
) 
select distinct
 extractvalue(column_value, '//customerid') customer_id,
 extractvalue(column_value, '//customername') customer_name
from 
  table(XMLSequence((select extract(p_x, '/results/return') x from params)))

如果需要,从数据集重建 XML:

SQLFiddle

with params as (
  select 
    sys.xmltype('  
      -- same XML text as in previous examples ------- 
   ') p_x 
 from dual
) 
select 
  XMLElement("results",
    XMLAgg(
      XMLElement("return",
        XMLConcat(
          XMLElement("customerid", customer_id),
          XMLElement("customername", customer_name)
        )
      )
    )           
  ).getclobval()  
from (  
  select distinct
   extractvalue(column_value, '//customerid') customer_id,
   extractvalue(column_value, '//customername') customer_name
  from 
    table(XMLSequence((select extract(p_x, '/results/return') x from params)))
)
于 2013-08-09T16:31:51.667 回答