拆分 XMLTYPE 以根据条件创建两个 XMLTYPE
Posted
技术标签:
【中文标题】拆分 XMLTYPE 以根据条件创建两个 XMLTYPE【英文标题】:Split XMLTYPE to Create two XMLTYPES based on conditions 【发布时间】:2014-09-05 16:45:47 【问题描述】:我有一个 Oracle 表,其中包含存储在 XMLTYPE 中的多个 XML 文件。虽然我可以查询和更新 XML 类型,但我正在尝试编写一个过程,该过程将采用一个 XML 并根据某些条件将两个新 XMLTYPES 插入到同一个表中。
例如,如果以下内容存储在我的 XMLTYPE 中,我想创建两条消息,均包含所有标题信息,但一条包含排名/位置最多为 5 的消息行(将返回两行)和其他排名/位置大于 5(将返回三行):
<DistrictMsg timestamp="2014-09-05T04:45:00">
<Publication xmlns:ns1="http://www.mynamespace.co.uk">
<TopicID>ENGLISH_DISTRICTS</TopicID>
</Publication>
<Message xmlns="http://www.mynamespace.co.uk">
<ns1:MessageHeader xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:MessageType>
<ns1:ID>EnglishDistricts2014</ns1:ID>
</ns1:MessageType>
<ns1:DocType>
<ns1:InternalName>
<ns1:ID>DistrictByPopulation</ns1:ID>
</ns1:InternalName>
</ns1:DocType>
</ns1:MessageHeader>
<ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:District>
<ns1:Name>Birmingham</ns1:Name>
</ns1:District>
<ns1:Population measure="1000">1074.3</ns1:Population>
<DistRank>
<PopulationRank>
<Position>1</Position>
</PopulationRank>
</DistRank>
</ns1:MessageLine>
<ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:District>
<ns1:Name>Manchester</ns1:Name>
</ns1:District>
<ns1:Population measure="1000">502.9</ns1:Population>
<DistRank>
<PopulationRank>
<Position>7</Position>
</PopulationRank>
</DistRank>
</ns1:MessageLine>
<ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:District>
<ns1:Name>Liverpool</ns1:Name>
</ns1:District>
<ns1:Population measure="1000">465.7</ns1:Population>
<DistRank>
<PopulationRank>
<Position>9</Position>
</PopulationRank>
</DistRank>
</ns1:MessageLine>
<ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:District>
<ns1:Name>Doncaster</ns1:Name>
</ns1:District>
<ns1:Population measure="1000">302.5</ns1:Population>
<DistRank>
<PopulationRank>
<Position>34</Position>
</PopulationRank>
</DistRank>
</ns1:MessageLine>
<ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:District>
<ns1:Name>Cornwall</ns1:Name>
</ns1:District>
<ns1:Population measure="1000">533.8</ns1:Population>
<DistRank>
<PopulationRank>
<Position>4</Position>
</PopulationRank>
</DistRank>
</ns1:MessageLine>
</Message>
</DistrictMsg>
【问题讨论】:
【参考方案1】:您可以通过使用 deletexml 删除不需要的条目来做到这一点。要返回不超过 5 的条目,我已经删除了所有大于 5 的条目。同样,要返回大于 5 的条目,我已经删除了小于或等于 5 的条目。 这是我的解决方案,希望对您有所帮助:
with xml_data as(
select xmltype('
<DistrictMsg timestamp="2014-09-05T04:45:00">
<Publication xmlns:ns1="http://www.mynamespace.co.uk">
<TopicID>ENGLISH_DISTRICTS</TopicID>
</Publication>
<Message xmlns="http://www.mynamespace.co.uk">
<ns1:MessageHeader xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:MessageType>
<ns1:ID>EnglishDistricts2014</ns1:ID>
</ns1:MessageType>
<ns1:DocType>
<ns1:InternalName>
<ns1:ID>DistrictByPopulation</ns1:ID>
</ns1:InternalName>
</ns1:DocType>
</ns1:MessageHeader>
<ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:District>
<ns1:Name>Birmingham</ns1:Name>
</ns1:District>
<ns1:Population measure="1000">1074.3</ns1:Population>
<DistRank>
<PopulationRank>
<Position>1</Position>
</PopulationRank>
</DistRank>
</ns1:MessageLine>
<ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:District>
<ns1:Name>Manchester</ns1:Name>
</ns1:District>
<ns1:Population measure="1000">502.9</ns1:Population>
<DistRank>
<PopulationRank>
<Position>7</Position>
</PopulationRank>
</DistRank>
</ns1:MessageLine>
<ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:District>
<ns1:Name>Liverpool</ns1:Name>
</ns1:District>
<ns1:Population measure="1000">465.7</ns1:Population>
<DistRank>
<PopulationRank>
<Position>9</Position>
</PopulationRank>
</DistRank>
</ns1:MessageLine>
<ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:District>
<ns1:Name>Doncaster</ns1:Name>
</ns1:District>
<ns1:Population measure="1000">302.5</ns1:Population>
<DistRank>
<PopulationRank>
<Position>34</Position>
</PopulationRank>
</DistRank>
</ns1:MessageLine>
<ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
<ns1:District>
<ns1:Name>Cornwall</ns1:Name>
</ns1:District>
<ns1:Population measure="1000">533.8</ns1:Population>
<DistRank>
<PopulationRank>
<Position>4</Position>
</PopulationRank>
</DistRank>
</ns1:MessageLine>
</Message>
</DistrictMsg>') xtype
from dual)
select
xmlserialize(document
deletexml(xtype, '//ns1:MessageLine[ns1:DistRank/ns1:PopulationRank/ns1:Position[text()>5]]', 'xmlns:ns1="http://www.mynamespace.co.uk"')
as clob indent size = 2) up_to_five,
xmlserialize(document
deletexml(xtype, '//ns1:MessageLine[ns1:DistRank/ns1:PopulationRank/ns1:Position[text()<=5]]', 'xmlns:ns1="http://www.mynamespace.co.uk"')
as clob indent size = 2) greater_than_five
from xml_data;
【讨论】:
以上是关于拆分 XMLTYPE 以根据条件创建两个 XMLTYPE的主要内容,如果未能解决你的问题,请参考以下文章
为啥不能通过 DBLink 发送 Oracle XMLType?
根据开始和结束索引(保存在两个向量中)并使用条件将 data.frame 拆分为较小的 data.frame