读取 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'

db<>fiddle