2012-12-20 48 views
3

這是我的SQL。我似乎無法從這件事中獲得單一的價值。它只適用於我刪除所有xmlns屬性。鑑於SQL Server中的以下XML,我如何獲得值?

我認爲問題在於這個XML包含2個默認命名空間,一個附加到Response元素,另一個附加到Shipment元素。

DECLARE @xml XML 
SET @xml = '<TrackResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Response xmlns="http://www.ups.com/XMLSchema/XOLTWS/Common/v1.0"> 
    <ResponseStatus> 
     <Code>1</Code> 
     <Description>Success</Description> 
    </ResponseStatus> 
    <TransactionReference /> 
    </Response> 
    <Shipment xmlns="http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0"> 
    <InquiryNumber> 
     <Code>01</Code> 
     <Description>ShipmentIdentificationNumber</Description> 
     <Value>1ZA50209234098230</Value> 
    </InquiryNumber> 
    <ShipperNumber>A332098</ShipperNumber> 
    <ShipmentAddress> 
     <Type> 
     <Code>01</Code> 
     <Description>Shipper Address</Description> 
     </Type> 
     <Address> 
     <AddressLine>123 HWY X</AddressLine> 
     <City>SOMETOWN</City> 
     <StateProvinceCode>SW</StateProvinceCode> 
     <PostalCode>20291 1234</PostalCode> 
     <CountryCode>US</CountryCode> 
     </Address> 
    </ShipmentAddress> 
    <ShipmentWeight> 
     <UnitOfMeasurement> 
     <Code>LBS</Code> 
     </UnitOfMeasurement> 
     <Weight>0.00</Weight> 
    </ShipmentWeight> 
    <Service> 
     <Code>42</Code> 
     <Description>UPS GROUND</Description> 
    </Service> 
    <Package> 
     <TrackingNumber>1ZA50209234098230</TrackingNumber> 
     <PackageServiceOption> 
     <Type> 
      <Code>01</Code> 
      <Description>Signature Required</Description> 
     </Type> 
     </PackageServiceOption> 
     <Activity> 
     <ActivityLocation> 
      <Address> 
      <City>SOMEWHERE</City> 
      <StateProvinceCode>PA</StateProvinceCode> 
      <CountryCode>US</CountryCode> 
      </Address> 
     </ActivityLocation> 
     <Status> 
      <Type>X</Type> 
      <Description>Damage reported./Damage claim under investigation.</Description> 
      <Code>UY</Code> 
     </Status> 
     <Date>20120424</Date> 
     <Time>125000</Time> 
     </Activity> 
     <Activity> 
     <ActivityLocation> 
      <Address> 
      <City>SOMEWHERE</City> 
      <StateProvinceCode>PA</StateProvinceCode> 
      <CountryCode>US</CountryCode> 
      </Address> 
     </ActivityLocation> 
     <Status> 
      <Type>X</Type> 
      <Description>All merchandise discarded. UPS will notify the sender with details of the damage.</Description> 
      <Code>GY</Code> 
     </Status> 
     <Date>20120423</Date> 
     <Time>115500</Time> 
     </Activity> 
     <PackageWeight> 
     <UnitOfMeasurement> 
      <Code>LBS</Code> 
     </UnitOfMeasurement> 
     <Weight>0.00</Weight> 
     </PackageWeight> 
    </Package> 
    </Shipment> 
</TrackResponse>' 

select Svc.Dsc.value('(/TrackResponse/Shipment/Service/Description)[1]', 'varchar(25)') 
from @xml.nodes('/TrackResponse') as Svc(Dsc) 
+0

什麼元素(S)你想獲得明確的價值*:TrackResponse[1]/*:? –

+0

我想/文字/ TrackResponse /貨運/服務/描述 –

+0

我真的需要LAST Activity元素的狀態類型文本(/ TrackResponse/Shipment/Package/Activity [2]/Status/Type)想了解如何正確指定名稱空間。 –

回答

2

兩個問題:

  • 你公然無視這就是<shipment>元素定義
  • 您的XQuery表達式是有點過

試試這個XML命名空間:

-- define XML namespace 
;WITH XMLNAMESPACES('http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0' AS ns) 
select 
    Svc.Dsc.value('(ns:Shipment/ns:Service/ns:Description)[1]', 'varchar(25)') 
from 
    -- this already selects all <TrackResponse> nodes - no need to repeat that in 
    -- your above call to .value() 
    @xml.nodes('/TrackResponse') as Svc(Dsc) 

給我的結果:

UPS GROUND 
3

正如@marc_s說,你忽略了XML命名空間。 Here is a sql fiddle example。這給了X,我認爲這就是你需要的。 Read this article for more。注:在xpath

--Results: X 

declare @xmlTable as table (
xmlData xml 
) 
insert into @xmlTable 
select '<TrackResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
      <Response xmlns="http://www.ups.com/XMLSchema/XOLTWS/Common/v1.0"> 
       ... 
     </TrackResponse>' 

;with xmlnamespaces(default 'http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0') 
select 
    x.xmlData.value('(/*:TrackResponse[1]/*:Shipment[1]/Package[1]/Activity[1]/Status[1]/Type[1])','varchar(100)') as all_snacks 
from @xmlTable x