Reputation: 2941
I've been through various posts on the same subject but I can't seem to be able to get to the data elements in my XML file.
Here is a snippet of my XML :
<ed:Certificate xmlns="http://sancrt.mpi.govt.nz/ecert/2013/ed-multiple-submission-schema.xsd" xmlns:ed="http://sancrt.mpi.govt.nz/ecert/2013/ed-submission-schema.xsd"> <ed:Status Code="39">Approved</ed:Status> <ed:LastUpdatedDate>2021-03-10T14:20:55+13:00</ed:LastUpdatedDate> <ed:Identifiers>
<ed:CertificateID>NZL2021/MEABC/26913T</ed:CertificateID>
<ed:TemplateID>ED1.6</ed:TemplateID> </ed:Identifiers> <ed:Exhausted>true</ed:Exhausted> <ed:AutoApproval>false</ed:AutoApproval> <ed:DepartureDate>2021-03-10</ed:DepartureDate> <ed:Parties>
<ed:ConsignorID>MEABC</ed:ConsignorID>
<ed:ConsigneeID>FLIGHT1</ed:ConsigneeID> </ed:Parties> <ed:Transport>
<ed:Ports>
<ed:LoadingPortID>NZTRG</ed:LoadingPortID>
</ed:Ports>
<ed:FinalDestination>OAKLAND, United States</ed:FinalDestination>
<ed:TransportMode>1</ed:TransportMode>
<ed:LocalCarrier>MDH2</ed:LocalCarrier>
<ed:CarrierName> Ever Given</ed:CarrierName>
<ed:ConveyanceReference>V1234</ed:ConveyanceReference> </ed:Transport> <ed:Remarks>
<ed:Remark>
<ed:RemarkType>Unofficial Information</ed:RemarkType>
<ed:RemarkValue>Vessel ETD - 19/03/21\nTARE WEIGHT - 2880 KGS</ed:RemarkValue>
</ed:Remark> </ed:Remarks> <ed:Products>
<ed:Product>
<ed:ProductItem>1</ed:ProductItem>
<ed:Exhausted>true</ed:Exhausted>
<ed:Origin>AO</ed:Origin>
<ed:Description>BONELESS BEEF RUMP CAP</ed:Description>
<ed:CommonName>Bovine</ed:CommonName>
<ed:EligibilityCountries>
<ed:EligibilityCountryID>US</ed:EligibilityCountryID>
</ed:EligibilityCountries>
<ed:IntendedUse>consumption</ed:IntendedUse>
<ed:GrossWeight unitCode="KGM">296.4</ed:GrossWeight>
<ed:NetWeight unitCode="KGM">271.6</ed:NetWeight>
<ed:Remarks>
<ed:Remark>
<ed:RemarkType>Product Statement</ed:RemarkType>
<ed:RemarkValue>Item No. 81625\nLabel Approval 2659305 & 91060858</ed:RemarkValue>
</ed:Remark>
</ed:Remarks>
<ed:Classifications>
<ed:Classification>
<ed:ClassificationType>Temperature</ed:ClassificationType>
<ed:ClassificationValue>chilled</ed:ClassificationValue>
</ed:Classification>
<ed:Classification>
<ed:ClassificationType>New Zealand Harmonised System Code</ed:ClassificationType>
<ed:ClassificationValue>020130</ed:ClassificationValue>
</ed:Classification>
<ed:Classification>
<ed:ClassificationType>Halal Product</ed:ClassificationType>
<ed:ClassificationValue>1</ed:ClassificationValue>
</ed:Classification>
</ed:Classifications>
<ed:Containers>
<ed:Container>
<ed:ID>CGMU3099999</ed:ID>
<ed:Seals>
<ed:ID>NZMPIXXXXX</ed:ID>
</ed:Seals>
</ed:Container>
</ed:Containers>
<ed:Packaging>
<ed:Package>
<ed:Quantity>29</ed:Quantity>
<ed:Type>CT</ed:Type>
<ed:Level>1</ed:Level>
<ed:ShippingMarks>
<ed:Name>MABC\n26913</ed:Name>
</ed:ShippingMarks>
</ed:Package>
</ed:Packaging>
<ed:Processes>
<ed:Process>
<ed:ProcessTypeCode>SLT</ed:ProcessTypeCode>
<ed:StartDate>2021-03-01</ed:StartDate>
<ed:EndDate>2021-03-01</ed:EndDate>
<ed:DateOverride>false</ed:DateOverride>
<ed:Premise>
<ed:ID>MEABC</ed:ID>
</ed:Premise>
</ed:Process>
<ed:Process>
<ed:ProcessTypeCode>PRO</ed:ProcessTypeCode>
<ed:StartDate>2021-03-02</ed:StartDate>
<ed:EndDate>2021-03-02</ed:EndDate>
<ed:DateOverride>false</ed:DateOverride>
<ed:Premise>
<ed:ID>MEABC</ed:ID>
</ed:Premise>
</ed:Process>
<ed:Process>
<ed:ProcessTypeCode>CST</ed:ProcessTypeCode>
<ed:StartDate>2021-03-02</ed:StartDate>
<ed:EndDate>2021-03-10</ed:EndDate>
<ed:DateOverride>false</ed:DateOverride>
<ed:Premise>
<ed:ID>MEABC</ed:ID>
</ed:Premise>
</ed:Process>
</ed:Processes>
</ed:Product>
</ed:Products>
</ed:Certificate>
This is what I have tried so far - Figured if I can access one element, I can slowly work on the rest
if OBJECT_ID('tempdb..#XmlImportTest') is not null
drop table #XmlImportTest
CREATE TABLE #XmlImportTest(
xmlFileName VARCHAR(300) NOT NULL,
xml_data XML NOT NULL
);
DECLARE @xmlFileName VARCHAR(200) ='K:\Upload\CSNXML\WaybillXml.xml'
EXEC('INSERT INTO #XmlImportTest(xmlFileName, xml_data)
SELECT ''' + @xmlFileName + ''', xmlData
FROM(
SELECT *
FROM OPENROWSET (BULK ''' + @xmlFileName + ''', SINGLE_BLOB) AS XMLDATA
) AS FileImport (XMLDATA)
')
DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)
SELECT @xml = (SELECT xml_data from #XmlImportTest)
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)
SELECT @xml = (SELECT xml_data from #XmlImportTest)
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
;WITH XMLNAMESPACES ('http://sancrt.mpi.govt.nz/ecert/2013/ed-multiple-submission-schema.xsd' AS ed)
SELECT
p.value(N'@ProductItem',N'nvarchar(10)') AS ProductItem
FROM
@xml.nodes('/Certificate')
AS A(p)
CROSS APPLY a.p.nodes(N'Products/Product') AS B(m);
I don't get any results returned.
I get the same result using OPENROWSET as well.
Can someone please tell me how I can access this data element.
Upvotes: 0
Views: 56
Reputation: 8809
You seem to be getting confused about XML Namespaces. The example document defines two namespace URIs:
ed
namespace prefix that, by eyeballing it, seems to be used on every element in the document so might as well be the default namespace.Your simplest example is trying to extract the value of the /Certificate/Products/Product/ProductItem
elements which could be done as simply as:
with xmlnamespaces (
default 'http://sancrt.mpi.govt.nz/ecert/2013/ed-submission-schema.xsd'
)
select productItem.value(N'text()[1]', N'int') as ProductItem
from @xml.nodes('/Certificate/Products/Product/ProductItem') as p(productItem);
Expanding on this to select a few more values, you can see the @
being used here to access the unitCode
attribute of an element:
with xmlnamespaces (
default 'http://sancrt.mpi.govt.nz/ecert/2013/ed-submission-schema.xsd'
)
select
product.value(N'(ProductItem/text())[1]', N'int') as ProductItem,
product.value(N'(Exhausted/text())[1]', N'bit') as Exhausted,
product.value(N'(Origin/text())[1]', N'nvarchar(2)') as Origin,
product.value(N'(GrossWeight/text())[1]', N'decimal(19,1)') as GrossWeight,
product.value(N'(GrossWeight/@unitCode)[1]', N'nvarchar(3)') as GrossWeightUnitCode
from @xml.nodes('/Certificate/Products/Product') as p(product);
It should be clear from the above two queries that the namespace prefixes used XPath query don't have to be the same as the ones used in the XML document - it's the namespace URIs themselves that matter. The prefixes in the document are used to link the elements (and sometimes attributes) to their namespace URIs, the prefixes used in XPath can be completely different so long as they reference the correct namespace URIs. e.g. this query returns the same result as the second example above, despite their being no submission
prefixes in the source XML:
with xmlnamespaces (
'http://sancrt.mpi.govt.nz/ecert/2013/ed-multiple-submission-schema.xsd' as multiple,
'http://sancrt.mpi.govt.nz/ecert/2013/ed-submission-schema.xsd' as submission
)
select
product.value(N'(submission:ProductItem/text())[1]', N'int') as ProductItem,
product.value(N'(submission:Exhausted/text())[1]', N'bit') as Exhausted,
product.value(N'(submission:Origin/text())[1]', N'nvarchar(2)') as Origin,
product.value(N'(submission:GrossWeight/text())[1]', N'decimal(19,1)') as GrossWeight,
product.value(N'(submission:GrossWeight/@unitCode)[1]', N'nvarchar(3)') as GrossWeightUnitCode,
product.value(N'(submission:Remarks/submission:Remark/submission:RemarkType/text())[1]', N'nvarchar(50)') as item_remark
from @xml.nodes('/submission:Certificate/submission:Products/submission:Product') as p(product);
Upvotes: 2