读取 XML CLOB 列中的标签
Reading tags in an XML CLOB column
我在这里搜索了几篇文章并尝试了不同的方法。我没有得到错误,但我也没有得到输出。
在我们的系统中,我们将传入的 xml 交易存储在 CLOB 列 L80T2.tridata
中,现在用户希望在新交易到来时得到警告,以便他们可以检查是否填充了数据库中的所有重要字段。
在示例中,我希望将 PartId 作为输出,即 <Id>R31312/CL7C</Id>
这是完整的xml
<MaXML_Envelope version="0140"xsi:schemaLocation="http://www.xxx.kom/Distro ../../../../mastd/xsd/MaXMLDoc/0140_PartUpdate_0100.xsd ">
<PartUpdate version="0100">
<ControlArea>
<Sender>
<Division>A1</Division>
<Confirmation>0</Confirmation>
</Sender>
<CreationDateTime>2022-02-15T00:00:00Z</CreationDateTime>
<RefId>
<ReferenceId>90000206</ReferenceId>
</RefId>
<TransactionType>LP04</TransactionType>
<SenderId>TRNM</SenderId>
<ReceiverId>FMHW</ReceiverId>
</ControlArea>
<DataArea>
<DataBaseTransaction sequence="1">
<PartUpdate>
<PartId>
===> <Id>R31312/CL7C</Id>
<Revision>9105</Revision>
<Division>A1</Division>
</PartId>
<Description>1606058</Description>
<UnitType/>
<PartToleranceArea>
<Inspection>N</Inspection>
</PartToleranceArea>
<UserArea>
<Wadmkey/>
<Description>1606058</Description>
<LanguageDescr_Segment sequence="1">
<DescrLanguage>EN</DescrLanguage>
<Description>1606058</Description>
</LanguageDescr_Segment>
<PartType>C</PartType>
<PartWeight>0.0</PartWeight>
<PartWeightUnit>KGM</PartWeightUnit>
<SingleUnitInstance/>
<HandlingUnitInstance/>
<PackCode/>
<ComCode/>
</UserArea>
</PartUpdate>
</DataBaseTransaction>
</DataArea>
</PartUpdate>
</MaXML_Envelope>
到目前为止我已经完成了以下查询 (sqlplus)
SELECT XMLQUERY(
'declare default element namespace "http://www.xxx.kom/Distro ../../../../mastd/xsd/MaXMLDoc/0140_PartUpdate_0100.xsd"; (: :)
/PartUpdate/DataArea/DataBaseTransaction/PartId/Id/text()'
PASSING XMLTYPE(L80T2.tridata)
RETURNING CONTENT
) myxmldata, L79T1.trno, L79T1.comtype
from L79T1
inner join L80T2 on (L80T2.trno = L79T1.trno)
where L79T1.trtype = '702'
这是上述查询的输出
MYXMLDATA
------------------
TRNO COMT
---------- ----
161657423 MQS
161672521 MQS
161666181 MQS
我做错了什么?
我期待这样的结果:
MYXMLDATA TRNO COMT
----------- --------- ----
R31312/CL7C 161657423 MQS
V34132/AB 161672521 MQS
OR-12BC 161666181 MQS
感谢您的帮助。
您的路径缺少根 MaXML_Envelope
节点和中间 PartUpdate
节点。
所以这个:
/PartUpdate/DataArea/DataBaseTransaction/PartId/Id/text()
应该是:
/MaXML_Envelope/PartUpdate/DataArea/DataBaseTransaction/PartUpdate/PartId/Id/text()
您也不需要声明默认命名空间,至少对于您所展示的内容而言;但是您的 XML 应该声明 xsi
命名空间(或者必须声明,否则您将看不到现在的结果;所以您在发布时丢失了它?)。
您可能还想调用 getStringVal()
以获得 varchar2
结果。
完整:
SELECT XMLQUERY(
'/MaXML_Envelope/PartUpdate/DataArea/DataBaseTransaction/PartUpdate/PartId/Id/text()'
PASSING XMLTYPE(L80T2.tridata)
RETURNING CONTENT
).getStringVal() myxmldata, L79T1.trno, L79T1.comtype
from L79T1
inner join L80T2 on (L80T2.trno = L79T1.trno)
where L79T1.trtype = '702'
我在这里搜索了几篇文章并尝试了不同的方法。我没有得到错误,但我也没有得到输出。
在我们的系统中,我们将传入的 xml 交易存储在 CLOB 列 L80T2.tridata
中,现在用户希望在新交易到来时得到警告,以便他们可以检查是否填充了数据库中的所有重要字段。
在示例中,我希望将 PartId 作为输出,即 <Id>R31312/CL7C</Id>
这是完整的xml
<MaXML_Envelope version="0140"xsi:schemaLocation="http://www.xxx.kom/Distro ../../../../mastd/xsd/MaXMLDoc/0140_PartUpdate_0100.xsd ">
<PartUpdate version="0100">
<ControlArea>
<Sender>
<Division>A1</Division>
<Confirmation>0</Confirmation>
</Sender>
<CreationDateTime>2022-02-15T00:00:00Z</CreationDateTime>
<RefId>
<ReferenceId>90000206</ReferenceId>
</RefId>
<TransactionType>LP04</TransactionType>
<SenderId>TRNM</SenderId>
<ReceiverId>FMHW</ReceiverId>
</ControlArea>
<DataArea>
<DataBaseTransaction sequence="1">
<PartUpdate>
<PartId>
===> <Id>R31312/CL7C</Id>
<Revision>9105</Revision>
<Division>A1</Division>
</PartId>
<Description>1606058</Description>
<UnitType/>
<PartToleranceArea>
<Inspection>N</Inspection>
</PartToleranceArea>
<UserArea>
<Wadmkey/>
<Description>1606058</Description>
<LanguageDescr_Segment sequence="1">
<DescrLanguage>EN</DescrLanguage>
<Description>1606058</Description>
</LanguageDescr_Segment>
<PartType>C</PartType>
<PartWeight>0.0</PartWeight>
<PartWeightUnit>KGM</PartWeightUnit>
<SingleUnitInstance/>
<HandlingUnitInstance/>
<PackCode/>
<ComCode/>
</UserArea>
</PartUpdate>
</DataBaseTransaction>
</DataArea>
</PartUpdate>
</MaXML_Envelope>
到目前为止我已经完成了以下查询 (sqlplus)
SELECT XMLQUERY(
'declare default element namespace "http://www.xxx.kom/Distro ../../../../mastd/xsd/MaXMLDoc/0140_PartUpdate_0100.xsd"; (: :)
/PartUpdate/DataArea/DataBaseTransaction/PartId/Id/text()'
PASSING XMLTYPE(L80T2.tridata)
RETURNING CONTENT
) myxmldata, L79T1.trno, L79T1.comtype
from L79T1
inner join L80T2 on (L80T2.trno = L79T1.trno)
where L79T1.trtype = '702'
这是上述查询的输出
MYXMLDATA
------------------
TRNO COMT
---------- ----
161657423 MQS
161672521 MQS
161666181 MQS
我做错了什么?
我期待这样的结果:
MYXMLDATA TRNO COMT
----------- --------- ----
R31312/CL7C 161657423 MQS
V34132/AB 161672521 MQS
OR-12BC 161666181 MQS
感谢您的帮助。
您的路径缺少根 MaXML_Envelope
节点和中间 PartUpdate
节点。
所以这个:
/PartUpdate/DataArea/DataBaseTransaction/PartId/Id/text()
应该是:
/MaXML_Envelope/PartUpdate/DataArea/DataBaseTransaction/PartUpdate/PartId/Id/text()
您也不需要声明默认命名空间,至少对于您所展示的内容而言;但是您的 XML 应该声明 xsi
命名空间(或者必须声明,否则您将看不到现在的结果;所以您在发布时丢失了它?)。
您可能还想调用 getStringVal()
以获得 varchar2
结果。
完整:
SELECT XMLQUERY(
'/MaXML_Envelope/PartUpdate/DataArea/DataBaseTransaction/PartUpdate/PartId/Id/text()'
PASSING XMLTYPE(L80T2.tridata)
RETURNING CONTENT
).getStringVal() myxmldata, L79T1.trno, L79T1.comtype
from L79T1
inner join L80T2 on (L80T2.trno = L79T1.trno)
where L79T1.trtype = '702'