我是XML新手。我已经弄清楚如何从XML文件中查询和返回值(例如下面的例子)。但是,我遇到的问题是它只捕获'SerialNo'标记的第一个节点,因为标记具有相同的节点名称“SerialNo”重复。在XML文件中,它有4个SKU#TT234343的序列号,但它只给我第一个Serial11111。我完全陷入困境,不知道如何列出所有这些序列#。
我想询问SKU#TT234343的查询结果,如果可能,请列出所有4个序列号。
请帮忙。谢谢!
XML文件如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<ROOT>
<ShipNotice version="1" >
<InvoiceDate>01/01/2015</InvoiceDate>
<InvoiceNumber>6868686</InvoiceNumber>
<ShipDate>02/02/2015</ShipDate>
<ShipTime>2306</ShipTime>
<PONumber>P444444</PONumber>
<PODate>03/03/2015</PODate>
<ShipCode>XXX</ShipCode>
<ShipDescription>FedEx Economy</ShipDescription>
<ShipTo>
<AddressName>ShipABC</AddressName>
<AddressContact>Name1</AddressContact>
<AddressLine1>2222 Street Name</AddressLine1>
<AddressLine2> </AddressLine2>
<City>AUSTIN</City>
<State>TX</State>
<ZipCode>78111</ZipCode>
</ShipTo>
<BillTo>
<AddressName>BillABC</AddressName>
<AddressContact>Name1</AddressContact>
<AddressLine1>1234 Street Name</AddressLine1>
<AddressLine2>-SUITE 111</AddressLine2>
<City>Los Angeles</City>
<State>CA</State>
<ZipCode>95136</ZipCode>
</BillTo>
<TotalWeight>324</TotalWeight>
<EmptyCartonWGT>0</EmptyCartonWGT>
<NumberOfCarton>1</NumberOfCarton>
<DirectShipFlag>D</DirectShipFlag>
<ShipFromWarehouse>88</ShipFromWarehouse>
<ShipFromZip>94538</ShipFromZip>
<ShipTrackNo>33333333</ShipTrackNo>
<EndUserPONumber>55555555</EndUserPONumber>
<CustomerSONumber/>
<Package sequence="1" >
<TrackNumber>666666666</TrackNumber>
<PackageWeight>324</PackageWeight>
<Item sequence="1" >
<SOLineNo>1</SOLineNo>
<MfgPN>XYZ1111111</MfgPN>
<SKU>TT234343</SKU>
<ShipQuantity>4</ShipQuantity>
<CustPOLineNo>1</CustPOLineNo>
<CustSOLineNo/>
<Description>Server1234</Description>
<CustPN/>
<UPC/>
<UnitPrice>1000</UnitPrice>
<EndUserPOLineNo>0</EndUserPOLineNo>
<SerialNo>Serial11111</SerialNo>
<SerialNo>Serial22222</SerialNo>
<SerialNo>Serial33333</SerialNo>
<SerialNo>Serial44444</SerialNo>
</Item>
<Item sequence="2" >
<SOLineNo>2</SOLineNo>
<MfgPN>XYZ222222</MfgPN>
<SKU>TT8848788</SKU>
<ShipQuantity>4</ShipQuantity>
<CustPOLineNo>2</CustPOLineNo>
<CustSOLineNo/>
<Description>GGG localization</Description>
<CustPN/>
<UPC/>
<UnitPrice>0.00</UnitPrice>
<EndUserPOLineNo>0</EndUserPOLineNo>
<SerialNo/>
</Item>
</Package>
</ShipNotice>
</ROOT>
SQL查询:
DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)
EXEC sp_xml_preparedocument @hDoc OUTPUT, @xmlData
SELECT
InvoiceNumber, PONumber, PODate
, AddressName
, MfgPN, SerialNo
--, AddressContact, AddressLine1, AddressLine2, City, State, ZipCode
FROM OPENXML(@hDoc, '/ROOT/ShipNotice/Package/Item')
WITH
(
--- ################# Level 1 #################
InvoiceNumber [varchar](50) '../../InvoiceNumber',
PONumber [varchar](100) '../../PONumber',
PODate [varchar](100) '../../PODate',
--- ################# Level 2 #################
AddressName [varchar](100) '../../ShipTo/AddressName',
--- ################# Level 3 #################
MfgPN [varchar](100) 'MfgPN',
SerialNo [varchar](100) 'SerialNo'
)
答案 0 :(得分:1)
您可以尝试使用较新的技术XQuery而不是OPENXML()
。使用XQuery,您可以使用nodes()
方法在与输出中的行对应的元素上粉碎XML,并使用value()
提取元素值:
SELECT
shipnotice.value('InvoiceNumber[1]','varchar(20)') InvoiceNumber
, shipnotice.value('PONumber[1]','varchar(20)') PONumber
, shipnotice.value('PODate[1]','varchar(20)') PODate
, shipnotice.value('(ShipTo/AddressName)[1]','varchar(100)') AddressName
, item.value('MfgPN[1]','varchar(100)') MfgPN
, serialno.value('.','varchar(100)') SerialNo
FROM @XML.nodes('/ROOT/ShipNotice') as t(shipnotice)
OUTER APPLY shipnotice.nodes('Package/Item') as t2(item)
OUTER APPLY item.nodes('SerialNo') as t3(serialno)
<强> Sqlfiddle Demo
强>
输出
| InvoiceNumber | PONumber | PODate | AddressName | MfgPN | SerialNo |
|---------------|----------|------------|-------------|------------|-------------|
| 6868686 | P444444 | 03/03/2015 | ShipABC | XYZ1111111 | Serial11111 |
| 6868686 | P444444 | 03/03/2015 | ShipABC | XYZ1111111 | Serial22222 |
| 6868686 | P444444 | 03/03/2015 | ShipABC | XYZ1111111 | Serial33333 |
| 6868686 | P444444 | 03/03/2015 | ShipABC | XYZ1111111 | Serial44444 |
| 6868686 | P444444 | 03/03/2015 | ShipABC | XYZ222222 | |