繁体   English   中英

如何根据条件从 Oracle XMLTYPE 中删除节点?

[英]How to delete a node from Oracle XMLTYPE based on a condition?

我有一个存储在CLOB列中的 XML 数据,我想根据特定条件删除一些节点。

XML 数据示例:

<?xml version="1.0" encoding="UTF-8"?>
<payment>
  <person>
    <surname>Marco</surname>
    <name>Gralike</name>
    <salary>2345</salary>
  </person>
  <person>
    <surname>ABC</surname>
    <name>TEST</name>
    <salary>1234</salary>
    <person>
    <surname>Tiger</surname>
    <name>Scott</name>
    <salary>2222</salary>
  </person>
  </person>
 </payment>
 <payment>
  <person>
    <surname>BertJan</surname>
    <name>Meinders</name>
    <salary>3456</salary>
    <salary>125</salary>
  </person>
  <person>
    <surname>XYZ</surname>
    <name>TEST</name>
    <salary>1234</salary>
  </person>
 </payment>
 <payment>
  <person>
    <surname>Chris</surname>
    <name>Gralike</name>
    <salary>4567</salary>
  </person>
  <person>
    <surname>LMN</surname>
    <name>TEST</name>
    <salary>1234</salary>
  </person>
 </payment>

如果包含 TEST,我需要一个 Oracle PLSQL 脚本来删除所有人员标签。

最终输出将是:

<?xml version="1.0" encoding="UTF-8"?>
<payment>
  <person>
    <surname>Marco</surname>
    <name>Gralike</name>
    <salary>2345</salary>
  </person>
 </payment>
 <payment>
  <person>
    <surname>BertJan</surname>
    <name>Meinders</name>
    <salary>3456</salary>
    <salary>125</salary>
  </person>
 </payment>
 <payment>
  <person>
    <surname>Chris</surname>
    <name>Gralike</name>
    <salary>4567</salary>
  </person>
 </payment>

提前致谢。

您提供的XML没有根,因此XML解析器无法对其进行解析。

假设确实如此(例如payments ),如下所示:

create table t(txt clob);
insert into t values('<?xml version="1.0" encoding="UTF-8"?>
<payments>
    <payment>
        <person>
            <surname>Marco</surname>
            <name>Gralike</name>
            <salary>2345</salary>
        </person>
        <person>
            <surname>ABC</surname>
            <name>TEST</name>
            <salary>1234</salary>
            <person>
                <surname>Tiger</surname>
                <name>Scott</name>
                <salary>2222</salary>
            </person>
        </person>
    </payment>
    <payment>
        <person>
            <surname>BertJan</surname>
            <name>Meinders</name>
            <salary>3456</salary>
            <salary>125</salary>
        </person>
        <person>
            <surname>XYZ</surname>
            <name>TEST</name>
            <salary>1234</salary>
        </person>
    </payment>
    <payment>
        <person>
            <surname>Chris</surname>
            <name>Gralike</name>
            <salary>4567</salary>
        </person>
        <person>
            <surname>LMN</surname>
            <name>TEST</name>
            <salary>1234</salary>
        </person>
    </payment>
</payments>');

您可以使用此:

update t
set txt = to_clob(deletexml(
  xmltype(t.txt),
  '//payment/person[./name[text()="TEST"]]'
));

产生:

<?xml version="1.0" encoding="UTF-8"?>
<payments>
    <payment>
        <person>
            <surname>Marco</surname>
            <name>Gralike</name>
            <salary>2345</salary>
        </person>
    </payment>
    <payment>
        <person>
            <surname>BertJan</surname>
            <name>Meinders</name>
            <salary>3456</salary>
            <salary>125</salary>
        </person>
    </payment>
    <payment>
        <person>
            <surname>Chris</surname>
            <name>Gralike</name>
            <salary>4567</salary>
        </person>
    </payment>
</payments>

编辑:

如果要删除没有给定子节点的节点,请使用以下命令:

update t
set txt = to_clob(deletexml(
  xmltype(t.txt),
  '//payment[not(./person)]'
));

它将删除所有没有人的付款标签。

deleteXML()已被弃用。 如果可能的话,您应该使用XQuery更新。 如果完整路径是固定的,也请尝试避免使用'//'。

with XML_TABLE as 
(
   select XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>
<payments>
<payment>
    <person>
        <surname>Marco</surname>
        <name>Gralike</name>
        <salary>2345</salary>
    </person>
    <person>
        <surname>ABC</surname>
        <name>TEST</name>
        <salary>1234</salary>
        <person>
            <surname>Tiger</surname>
            <name>Scott</name>
            <salary>2222</salary>
        </person>
    </person>
</payment>
<payment>
    <person>
        <surname>BertJan</surname>
        <name>Meinders</name>
        <salary>3456</salary>
        <salary>125</salary>
    </person>
    <person>
        <surname>XYZ</surname>
        <name>TEST</name>
        <salary>1234</salary>
    </person>
</payment>
<payment>
    <person>
        <surname>Chris</surname>
        <name>Gralike</name>
        <salary>4567</salary>
    </person>
    <person>
        <surname>LMN</surname>
        <name>TEST</name>
        <salary>1234</salary>
    </person>
</payment>
</payments>') as XML_COLUMN from dual
)
SELECT XMLQuery(
    'copy $NEWXML := $XML modify (
      delete nodes $NEWXML/payments/payment/person[name[text()=$NAME]]
     )
     return $NEWXML'
     passing XML_COLUMN as "XML",
             'TEST' as "NAME"
     returning CONTENT
   )
from XML_TABLE
/

您可以在livesql.oracle.com上尝试使用SQL Workbench删除此代码

感谢您的样品。

<payment> 
<person>
 <surname>XYZ</surname> 
 <name>TEST</name> 
 <salary>1234</salary> 
 </person> 
<id>person 4</id> 
</payment> 

如果节点之一包含上述数据,则在使用deletexml之后,我得到以下信息:

<payment> 
<id>person 4</id> 
</payment> 

如果该节点不包含任何<person>标记,如何删除?

即如何删除下面的节点,因为它不包含<person>标签:

   <payment> 
    <id>person 4</id> 
    </payment>

这有效

with XML_TABLE as
(
   select XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>
<payments>
  <payment>
    <person>
     <surname>XYZ</surname>
  <name>TEST</name>
  <salary>1234</salary>
</person>
<id>person 4</id>
 </payment>
 <payment>
<id>person 5</id>
</payment>
 </payments>') as XML_COLUMN from dual
)
SELECT XMLQuery(
'copy $NEWXML := $XML modify (
  delete nodes $NEWXML/payments/payment[not(person)]
 )
 return $NEWXML'
 passing XML_COLUMN as "XML",
         'TEST' as "NAME"
 returning CONTENT
)
from XML_TABLE

<?xml version="1.0" encoding="WINDOWS-1252"?>
<payments>
  <payment>
 <person>
  <surname>XYZ</surname>
  <name>TEST</name>
  <salary>1234</salary>
</person>
  <id>person 4</id>
 </payment>
</payments>

SQL>

暂无
暂无

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

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