如何使用 XML 查询功能从 XML 节点查询值

问题描述 投票:0回答:1

我有以下 XML 数据:

DECLARE @x XML   
SET @x='<Orders>
<HeadingSection>
    <DocumentNameCode>Order</DocumentNameCode>
    <DetailSection>
        <LineItem LineItemNumber="10">
            <ItemId>123456789</ItemId>
            <ItemTypeId>EN</ItemTypeId>
            <AdditionalProductId Qualifier="ProductId">
                <Item>
                <ItemId>ABC</ItemId>
                <TypeId>SA</TypeId>
                </Item>
            </AdditionalProductId>
            <AdditionalProductId Qualifier="ProductId">
                <Item>
                <ItemId>XYZ</ItemId>
                <TypeId>IN</TypeId>
                </Item>
            </AdditionalProductId>
        </LineItem>
    </DetailSection>
    <SummarySection/>
</HeadingSection>
</Orders>'

我已经使用了以下T-Sql脚本(必须有光标)

DECLARE @xmlQuittungPOS XML
DECLARE quittungCurPOS CURSOR FOR
    SELECT QuittungXMLPOS = T.X.query('.')         
    FROM @x.nodes('/Orders/HeadingSection/DetailSection/LineItem') AS T(X)  
    
OPEN quittungCurPOS
    
FETCH NEXT FROM quittungCurPOS INTO @xmlQuittungPOS
    
WHILE @@FETCH_STATUS = 0
BEGIN

INSERT INTO dbo.tempPOS (

GTIN
,edi_PIA_SA
,edi_PIA_IN

)


SELECT

GTIN = T.X.query('/LineItem[ItemTypeId = "BP"]').value('(/LineItem/ItemId)[1]','VARCHAR(100)') -- funktioniert / works

,edi_PIA_SA = T.X.query('/LineItem/AdditionalProductId/Item[TypeId = "SA"]').value('(/LineItem/AdditionalProductId/Item/ItemId)[1]','VARCHAR(255)') -- funktioniert nicht / doesn't work

,edi_PIA_IN = T.X.query('/LineItem/AdditionalProductId/Item[TypeId = "IN"]').value('(/LineItem/AdditionalProductId/Item/ItemId)[1]','VARCHAR(255)') -- funktioniert nicht / doesn't work

FROM 
@xmlQuittungPOS.nodes('/LineItem') AS T(X)
    
FETCH NEXT FROM quittungCurPOS INTO @xmlQuittungPOS
END

CLOSE quittungCurPOS
DEALLOCATE quittungCurPOS

1.) GTIN -> 查询有效 2.) PIA_SA 和 PIA_IN -> 查询不起作用

问题:

我认为这是因为 '/LineItem/AdditionalProductId/Item[TypeId = "SA"]' 位于附加节点中。

问题:

如何获取

中TypeId“SA”和“IN”的值
<AdditionalProductId Qualifier="ProductId">
<Item>
<ItemId>**ABC**</ItemId>
<TypeId>SA</TypeId>
</Item>
</AdditionalProductId>

<AdditionalProductId Qualifier="ProductId">
<Item>
<ItemId>**XYZ**</ItemId>
<TypeId>IN</TypeId>
</Item>
</AdditionalProductId>

with .value('(/LineItem/AdditionalProductId/Item/ItemId)[1]','VARCHAR(255)')

!处于 1 级!

--

我知道。

级别 1 上的 SA -> .value('(/LineItem/AdditionalProductId/Item/ItemId)[1]','VARCHAR(255)') 级别 2 上的 SA -> .value('(/LineItem/AdditionalProductId/Item/ItemId)[2]','VARCHAR(255)')

但我现在需要查询类型

谢谢

sql-server t-sql xpath sqlxml
1个回答
1
投票

不清楚你在这里追求什么,所以我回答两者。如果您想要每个

Item
节点 1 行,那么您只需对
nodes
节点使用
Item
并获取
value
文本的
ItemId

DECLARE @xml xml = '<AdditionalProductId Qualifier="ProductId">
<Item>
<ItemId>**ABC**</ItemId>
<TypeId>SA</TypeId>
</Item>
</AdditionalProductId>

<AdditionalProductId Qualifier="ProductId">
<Item>
<ItemId>**XYZ**</ItemId>
<TypeId>IN</TypeId>
</Item>
</AdditionalProductId>
';

SELECT AP.I.value('(ItemId/text())[1]','varchar(15)') AS ItemId,
       AP.I.value('(TypeId/text())[1]','varchar(15)') AS TypeId
FROM (VALUES(@XML))V(X) --To give impression it's against a table
      CROSS APPLY V.X.nodes ('AdditionalProductId/Item')AP(I);

但是,如果您希望每个不同的

TypeID
值各有 1 列,您可以在 XML 中进行过滤:

SELECT X.AP.value('(AdditionalProductId/Item[TypeId[(text()[1])="SA"]]/ItemId/text())[1]','varchar(15)') AS ItemSA,
       X.AP.value('(AdditionalProductId/Item[TypeId[(text()[1])="IN"]]/ItemId/text())[1]','varchar(15)') AS ItemIN
FROM @xml.nodes ('/')X(AP); --To give impression it's against a table

或者使用之前的查询并使用条件聚合:

WITH Items AS(
    SELECT AP.I.value('(ItemId/text())[1]','varchar(15)') AS ItemId,
           AP.I.value('(TypeId/text())[1]','varchar(15)') AS TypeId
    FROM @xml.nodes ('AdditionalProductId/Item')AP(I))
SELECT MAX(CASE TypeID WHEN 'SA' THEN ItemId END) AS ItemSA,
       MAX(CASE TypeID WHEN 'IN' THEN ItemId END) AS ItemIN
FROM Items;
© www.soinside.com 2019 - 2024. All rights reserved.