How to extract data from xml in specific way sql server - sql-server

here is my sample xml
<NewDataSet>
<Employee>
<EmpID>1005</EmpID>
<Name> keith </Name>
<DOB>12/02/1981</DOB>
<Salary>10,500</Salary>
</Employee>
</NewDataSet>
from where i want to extract data and store in string variable like this way
SET #Data='EmpID=1005,Name='Keith',DOB='12/02/1981',Salary=10,500'
so show me the way to extract data from xml and re-arrange or store data in string variable the way i want but please give me suggested sql in such way which should work for different or any xml template. looking for idea. thanks

DECLARE #xmlVar AS XML
DECLARE #vcRow AS VARCHAR(500)
SET #xmlVar ='<NewDataSet>
<Employee>
<EmpID>1005</EmpID>
<Name> keith </Name>
<DOB>12/02/1981</DOB>
<Salary>10,500</Salary>
</Employee>
</NewDataSet>'
;with yourDataSet
AS (
SELECT
t.u.value('EmpID[1]','INT') AS EmpID
,t.u.value('Name[1]','VARCHAR(50)') AS Name
,t.u.value('DOB[1]','DATE') AS DOB
,t.u.value('Salary[1]','MONEY') AS Salary
FROM
#xmlVar.nodes('/NewDataSet/Employee') AS t(u) )
SELECT
/*#vcRow = */'EmpID='+ CAST(EmpID AS VARCHAR(50)) +',' +
'Name='''+Name +''',DOB=''' + CONVERT(VARCHAR(10),DOB,110) + ''',Salary='+CAST(Salary AS VARCHAR(50))
FROM
yourDataSet

Something like this would work. The query extracts all Employee sub-nodes and concatenates to a string. The script will only work if there's only one row in #tbl though but it just illustrates a way to get the string you want. It's not generic either, that would be a lot harder I imagine.
DECLARE #tbl TABLE(data XML NOT NULL);
INSERT INTO #tbl(data)VALUES('<NewDataSet>
<Employee>
<EmpID>1005</EmpID>
<Name> keith </Name>
<DOB>12/02/1981</DOB>
<Salary>10,500</Salary>
</Employee>
</NewDataSet>');
DECLARE #data VARCHAR(4000);
SELECT
#data =
'EmpID=' + N.T.value('EmpID[1]','VARCHAR(512)') + ',' +
'Name=''' + N.T.value('Name[1]','VARCHAR(512)') + ''',' +
'DOB=''' + N.T.value('DOB[1]','VARCHAR(512)') + ''',' +
'Salary=' + N.T.value('Salary[1]','VARCHAR(512)')
FROM
#tbl AS t
CROSS APPLY t.data.nodes('//Employee') AS N(T)
PRINT #data;

Related

XML output in SQL help needed

Hi I have the following code in SQL that outputs xml between 2 tables. The output is 90% correct but if possible add to the output and then also remove some of the output text.
I am not sure if SQL has the ability to code a type of a element in the output. Please see the code below with the output. Currently if possible I would like to make 2 changes to my current output. The changes are list at the end of the port
DECLARE #ID_Rechnung int = 1978,
#XMLData xml;
WITH XMLNAMESPACES ('?xml version="1.0" encoding="UTF-8"?' as ext)
SELECT
#XMLData = xmldat.xmldataCol
FROM
(
SELECT (
SELECT
-- HIER XML Daten generieren
[InvoiceHeader].[InvoiceDate] AS 'invoice-date',
([InvoiceHeader].[InvoiceNumber]) AS 'invoice-number',
cast(replace([InvoiceHeader].[GrossValue],' ','') as decimal(18,2)) AS 'gross-total',
cast(replace([InvoiceHeader].[NetValue],' ','') as decimal(18,2)) AS 'amount-due',
[InvoiceHeader].[VatRate] AS 'tax-rate',
cast(replace([InvoiceHeader].[VatValue],' ','') as decimal(18,2)) AS 'tax-amount',
[ImagePath] AS 'image-scan-url',
[InvoiceType] AS 'document-type',
[LegalEntityVATNo] AS 'account-type/id',
[LegalEntityName] AS 'account-type/name',
[SupplierCode] as 'supplier/number',
[Currency] as 'currency/code',
(
SELECT rtrim([InvoiceLines].[LineNumber]) AS [order-line-num]
, [PONumber] as [po-number],
CAST([InvoiceLines].[UnitPrice] AS decimal(18,2)) AS Price ,
[Quantity] as quantity,
[TaxAmount] as [tax-amount],
[LineTotal] as [total],
[Decsription] as description
FROM [InvoiceLines] WHERE [InvoiceLines].[DOCID] = #id_Rechnung
FOR XML PATH('Invoice-line'), ROOT('invoice-lines'), TYPE
)
FROM [InvoiceHeader]
WHERE [InvoiceHeader].[DOCID] = #ID_Rechnung
FOR XML PATH(''), TYPE, ROOT('invoice-header')
) AS xmldataCol
) AS xmldat;
SELECT #XMLData
.query('<invoice-header>
{
for $x in /invoice-header/*[local-name()!="root"]
return $x,
for $x in /invoice-header/root/r
return <invoice-lines>/<invoice-line>{$x/*}</invoice-line></invoice-lines>
}
</invoice-header>');
Output:
<invoice-header>
<invoice-date>20180509</invoice-date>
<invoice-number>1075440</invoice-number>
<gross-total>1376.67</gross-total>
<amount-due>1197.10</amount-due>
<tax-rate>15.00%</tax-rate>
<tax-amount>179.57</tax-amount>
<image-scan-url>\\INTEL-SQL01\Attachment\2018-06-20\7e0dd165-81d6-445a-95d1-8aac686d44ed\f9a1179c-2a54-480e-b97a-ce6ac7327ae0.000</image-scan-url>
<account-type>
<id>4010112052</id>
<name>CONSOLIDATEDPOWERPROJECTS</name>
</account-type>
<supplier>
<number>12345</number>
</supplier>
<currency>
<code>ZAR</code>
</currency>
<invoice-lines xmlns:ext="?xml version="1.0" encoding="UTF-8"?">
<Invoice-line>
<order-line-num>4</order-line-num>
<po-number>120934861</po-number>
<Price>50.00</Price>
<quantity>1.000000</quantity>
<tax-amount>7.500000</tax-amount>
<total>50.00</total>
<description>Test1</description>
</Invoice-line>
<Invoice-line>
<order-line-num>2</order-line-num>
<po-number>120934861</po-number>
<Price>10.00</Price>
<quantity>2.000000</quantity>
<tax-amount>4.500000</tax-amount>
<total>20.00</total>
<description>Test2</description>
</Invoice-line>
</invoice-lines>
</invoice-header>
1.How do I get rid of the following xmlns:ext="?xml version="1.0" encoding="UTF-8&in the line: "<invoice-lines xmlns:ext="?xml version="1.0" encoding="UTF-8"?">"
How would I code "<tax-amount>7.500000</tax-amount> to get the output": "<tax-amount type="decimal">7.500000</tax-amount>"
Without a minimal reproducible example it is not possible to give you a full working answer.
(1) As #JeroenMostert already pointed out, the
'?xml version="1.0" encoding="UTF-8"?'
is an XML prolog declaration. Just delete the following line:
WITH XMLNAMESPACES ('?xml version="1.0" encoding="UTF-8"?' as ext)
(2) Here is a conceptual example how to add an attribute to an XML element. What is important here is a sequential order of adding, i.e. attribute shall be first, element itself is 2nd.
SQL
DECLARE #tbl TABLE (ID INT IDENTITY PRIMARY KEY, [tax-amount] VARCHAR(20));
INSERT INTO #tbl ([tax-amount]) VALUES
(N'7.500000'),
(N'18.000000');
SELECT
'decimal' AS [tax-amount/#type]
, [tax-amount]
FROM #tbl
FOR XML PATH('r'), TYPE, ROOT('root');
Output
<root>
<r>
<tax-amount type="decimal">7.500000</tax-amount>
</r>
<r>
<tax-amount type="decimal">18.000000</tax-amount>
</r>
</root>

How to join element values in XQuery for SQL Server?

If I have this XML
<TradingInquirySearchResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SearchTerm>test</SearchTerm>
<CompanyFound>true</CompanyFound>
<CompanyInfoCollection>
<CompanyInfo>
<CompanyID>26</CompanyID>
<CompanyName>test</CompanyName>
<Status>Unrestricted</Status>
<SearchTags>
<Tag>test2</Tag>
<Tag>test3</Tag>
<Tag>test4</Tag>
</SearchTags>
</CompanyInfo>
</CompanyInfoCollection>
</TradingInquirySearchResult>
I want to get "test2;test3;test4". How can I join the values of <Tag> for the first <CompanyInfo> tag?
I tried TransactionData.value('(/TradingInquirySearchResult/CompanyInfoCollection/CompanyInfo[1]/SearchTags/Tag)[1]', 'nvarchar(1000)')
but it didn't work.
Thanks
As you're using SQL Server 2012 (or rather not 2017+) the common way to aggregate strings is to use FOR XML PATH and STUFF, and you can get the multiple values for the node Tag using the nodes operator. This gives you the below:
DECLARE #XML xml = '
<TradingInquirySearchResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SearchTerm>test</SearchTerm>
<CompanyFound>true</CompanyFound>
<CompanyInfoCollection>
<CompanyInfo>
<CompanyID>26</CompanyID>
<CompanyName>test</CompanyName>
<Status>Unrestricted</Status>
<SearchTags>
<Tag>test2</Tag>
<Tag>test3</Tag>
<Tag>test4</Tag>
</SearchTags>
</CompanyInfo>
</CompanyInfoCollection>
</TradingInquirySearchResult>';
SELECT STUFF((SELECT N';' + ST.Tag.value('(./text())[1]','nvarchar(100)')
FROM (VALUES(#XML))V(X)
CROSS APPLY V.X.nodes('/TradingInquirySearchResult/CompanyInfoCollection/CompanyInfo/SearchTags/Tag') ST(Tag)
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,1,N'') AS Tags
Edit for guess when multiple companies.
If you only want the first company, then yes, using [1] would work:
DECLARE #XML xml = '
<TradingInquirySearchResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SearchTerm>test</SearchTerm>
<CompanyFound>true</CompanyFound>
<CompanyInfoCollection>
<CompanyInfo>
<CompanyID>26</CompanyID>
<CompanyName>test</CompanyName>
<Status>Unrestricted</Status>
<SearchTags>
<Tag>test2</Tag>
<Tag>test3</Tag>
<Tag>test4</Tag>
</SearchTags>
</CompanyInfo>
<CompanyInfo>
<CompanyID>27</CompanyID>
<CompanyName>Sample</CompanyName>
<Status>Restricted</Status>
<SearchTags>
<Tag>test6</Tag>
<Tag>test7</Tag>
<Tag>test8</Tag>
</SearchTags>
</CompanyInfo>
</CompanyInfoCollection>
</TradingInquirySearchResult>';
SELECT STUFF((SELECT N';' + ST.Tag.value('(./text())[1]','nvarchar(100)')
FROM (VALUES(#XML))V(X)
CROSS APPLY V.X.nodes('/TradingInquirySearchResult/CompanyInfoCollection/CompanyInfo[1]/SearchTags/Tag') ST(Tag)
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,1,N'') AS Tags;
If, however, you want a row per company, then you would want to do something like this:
SELECT CIC.CI.value('(./CompanyID/text())[1]','nvarchar(50)') AS CompanyID,
STUFF((SELECT N';' + ST.Tag.value('(./text())[1]','nvarchar(100)')
FROM CIC.CI.nodes('./SearchTags/Tag') ST(Tag)
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,1,N'') AS Tags
FROM (VALUES(#XML))V(X)
CROSS APPLY V.X.nodes('/TradingInquirySearchResult/CompanyInfoCollection/CompanyInfo') CIC(CI);

SQL - String Manipulation

Context:
I have a view in SQL Server that tracks parameters a user inputs when they run an SSRS report (ReportServer.dbo.ExecutionLog). About 50 report parameters are saved as a string in a single column with ntext datatype. I would like to break this single column up into multiple columns for each parameter.
Details:
I query the report parameters like this:
SELECT ReportID, [Parameters]
FROM ReportServer.dbo.ExecutionLog
WHERE ReportID in (N'redacted')
and [Status] in (N'rsSuccess')
ORDER BY TimeEnd DESC
And here's a small subset of what the results look like:
alpha=123&bravo=9%2C33%2C76%2C23&charlie=91&delta=29&echo=11%2F2%2F2018%2012%3A00%3A00%20AM&foxtrot=11%2F1%2F2030%2012%3A00%3A00%20AM
Quesitons:
How can I get the results to look like this:
SQL Server 2017 is Python friendly. Is Python a better language to use in this scenario just for parsing purposes?
I've seen similar topics posted here, here & here. The parameters are dynamic so parsing via SQL string functions that involve counting characters doesn't apply. This question is relevant to more people than just me because there's a large population of people using SSRS. Tracking & formatting parameters in a more digestible way is valuable for all users of SSRS.
Here is a way using the built in STRING_SPLIT. I'm just not sure what the logic is for the stuff AFTER the date, so I would discarded it but I left it for you to decide.
DEMO
declare #table table (ReportID int identity(1,1), [Parameters] varchar(8000))
insert into #table
values
('alpha=123&bravo=9%2C33%2C76%2C23&charlie=91&delta=29&echo=11%2F2%2F2018%2012%3A00%3A00%20AM&foxtrot=11%2F1%2F2030%2012%3A00%3A00%20AM')
,('alpha=457893&bravo=9%2C33%2C76%2C23&charlie=91&delta=29&echo=11%2F2%2F2018%2012%3A00%3A00%20AM&foxtrot=11%2F1%2F2030%2012%3A00%3A00%20AM')
select
ReportID
,[Parameters]
,alpha = max(iif(value like 'alpha%',substring(value,charindex('=',value) + 1,99),null))
,bravo = max(iif(value like 'bravo%',substring(value,charindex('=',value) + 1,99),null))
,charlie = max(iif(value like 'charlie%',substring(value,charindex('=',value) + 1,99),null))
,delta = max(iif(value like 'delta%',substring(value,charindex('=',value) + 1,99),null))
,echo = max(iif(value like 'echo%',substring(value,charindex('=',value) + 1,99),null))
,foxtrot = max(iif(value like 'foxtrot%',substring(value,charindex('=',value) + 1,99),null))
from #table
cross apply string_split(replace(replace([Parameters],'%2C',','),'%2F','/'),'&')
group by ReportID, [Parameters]
Or, if they aren't static you can use a dynamic pivot. It'll take some massaging to get your columns in the correct order.
DEMO
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(substring([value],0,charindex('=',[value])))
from myTable
cross apply string_split(replace(replace([Parameters],'%2C',','),'%2F','/'),'&')
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select #cols
set #query = 'SELECT ReportID, ' + #cols + ' from
(
select ReportID
, ColName = substring([value],0,charindex(''='',[value]))
, ColVal = substring([value],charindex(''='',[value]) + 1,99)
from myTable
cross apply string_split(replace(replace([Parameters],''%2C'','',''),''%2F'',''/''),''&'')
) x
pivot
(
max(ColVal)
for ColName in (' + #cols + ')
) p '
execute(#query)
Split the string on the ampersand character.
Further split each row into two columns on the equals character.
In the second column, replace %2C with the comma character, and %2F with the forward-slash character, and so on with any other replacements as needed.
Use a dynamic-pivot to query the above in the format that you want.
Here's a method that starts with a lot of replaces.
To url-decode the string and transform it into an XML type.
Then it uses the XML functions to get the values for the columns.
Example snippet:
declare #Table table ([Parameters] varchar(200));
insert into #Table ([Parameters]) values
('alpha=123&bravo=9%2C33%2C76%2C23&charlie=91&delta=29&echo=11%2F2%2F2018%2012%3A00%3A00%20AM&foxtrot=11%2F1%2F2030%2012%3A00%3A00%20AM');
select
x.query('/x[key="alpha"]/val').value('.', 'int') as alpha,
x.query('/x[key="bravo"]/val').value('.', 'varchar(30)') as bravo,
x.query('/x[key="charlie"]/val').value('.', 'varchar(30)') as charlie,
x.query('/x[key="delta"]/val').value('.', 'varchar(30)') as delta,
convert(date, x.query('/x[key="echo"]/val').value('.', 'varchar(30)'), 103)as echo,
convert(date, x.query('/x[key="foxtrot"]/val').value('.', 'varchar(30)'), 103) as foxtrot
from #Table
cross apply (select cast('<x><key>'+
replace(replace(replace(replace(replace(
replace([Parameters],
'%2C',','),
'%2F','/'),
'%20',' '),
'%3A',':'),
'=','</key><val>'),
'&','</val></x><x><key>')
+'</val></x>' as XML) as x) ca
Test on db<>fiddle here

SQL Server FOR XML with nested sub-select

The following sql code
SELECT
b.GivenName [Individual/Name/FirstName] ,
b.FamilyName [Individual/Name/LastName] ,
b.Address_Country [Individual/Address/CountryCode] ,
b.AddressFree [Individual/Address/AddressFree]
FROM dbo.stage_Clients_Merge b
WHERE b.DWHClientNo = #dwhclientNo
FOR XML PATH('Owner'), TYPE
will generate an xml fragment
<Owner>
<Individual>
<Name>
<FirstName>Bob</FirstName>
<LastName>Smith</LastName>
</Name>
<Address>
<CountryCode>US</CountryCode>
<AddressFree>123,Utah</AddressFree>
</Address>
</Individual>
</Owner>
If I extend this query to include a sub-query to return, for example, all the orders associated with a individual using the following:
(SELECT
c.OrderIdentificationNumber [Individual/OrderNumber]
FROM
dbo.stage_Customer_Orders c
WHERE
c.CustomerNo = b.masterClient
FOR
XML PATH(''), TYPE)
I will get the individual section twice. How can I combine the two to return the following?
<Owner>
<Individual>
<OrderNo>12345</OrderNo>
<OrderNo>23456</OrderNo>
<Name>
<FirstName>Bob</FirstName>
<LastName>Smith</LastName>
</Name>
<Address>
<CountryCode>US</CountryCode>
<AddressFree>123,Utah</AddressFree>
</Address>
</Individual>
</Owner>
Try it like this
I set up a mock-up scenario for stand-alone solutions. Next time you have a question, you might try this on your own. This makes it much easier to understand your issue and create a fully working and testable solution for it.
DECLARE #stage_Clients_Merge TABLE(ID INT,FirstName VARCHAR(100),LastName VARCHAR(100),CountryCode VARCHAR(100),AdressFree VARCHAR(100));
INSERT INTO #stage_Clients_Merge VALUES
(1,'Bob','Smith','US','123/Utah')
,(2,'Jim','Doh','US','123/Maryland');
DECLARE #orders TABLE(CustomerID INT, OrderNo INT)
INSERT INTO #orders VALUES
(1,11111),(1,12222)
,(2,21111),(2,22222);
SELECT (SELECT OrderNo FROM #orders WHERE CustomerID=b.ID FOR XML PATH(''),TYPE) AS Individual
,FirstName AS [Individual/Name/FirstName]
,LastName AS [Individual/Name/LastName]
,CountryCode AS [Individual/Address/CountryCode]
,AdressFree AS [Individual/Address/AdressFree]
FROM #stage_Clients_Merge AS b
FOR XML PATH('Owner');
You can use a subquery and [data()] to just get the column values with no additional nesting - then use path as before:
SELECT
(SELECT c.OrderIdentificationNumber as [data()]
FROM dbo.stage_Customer_Orders c
WHERE c.CustomerNo = b.masterClient
For XML Path('OrderNo'), type) as [Individual],
b.GivenName [Individual/Name/FirstName] ,
b.FamilyName [Individual/Name/LastName] ,
b.Address_Country [Individual/Address/CountryCode] ,
b.AddressFree [Individual/Address/AddressFree]
FROM dbo.stage_Clients_Merge b
WHERE b.DWHClientNo = #dwhclientNo
FOR XML PATH('Owner'), TYPE

Casting a field to XML, querying it returns NULL records

I've a field on my table that is nvarchar(max) and contains XML document. Don't ask why it is nvarchar(max) instead of XML because I don't know it.
By the way, here is an extraction of a sample XML:
<?xml version="1.0" encoding="utf-16"?>
<ItemType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<AutoPay xmlns="urn:ebay:apis:eBLBaseComponents">true</AutoPay>
<Country xmlns="urn:ebay:apis:eBLBaseComponents">IT</Country>
<Currency xmlns="urn:ebay:apis:eBLBaseComponents">EUR</Currency>
<HitCounter xmlns="urn:ebay:apis:eBLBaseComponents">BasicStyle</HitCounter>
<ListingDuration xmlns="urn:ebay:apis:eBLBaseComponents">GTC</ListingDuration>
<ListingType xmlns="urn:ebay:apis:eBLBaseComponents">FixedPriceItem</ListingType>
<Location xmlns="urn:ebay:apis:eBLBaseComponents">Italy</Location>
<PaymentMethods xmlns="urn:ebay:apis:eBLBaseComponents">PayPal</PaymentMethods>
<PayPalEmailAddress xmlns="urn:ebay:apis:eBLBaseComponents">email#paypal.com</PayPalEmailAddress>
<PrimaryCategory xmlns="urn:ebay:apis:eBLBaseComponents">
<CategoryID>137084</CategoryID>
</PrimaryCategory>
<ShippingDetails xmlns="urn:ebay:apis:eBLBaseComponents">
<ShippingServiceOptions>
<ShippingService>StandardShippingFromOutsideUS</ShippingService>
<ShippingServiceCost currencyID="EUR">0</ShippingServiceCost>
<ShippingServiceAdditionalCost currencyID="EUR">0</ShippingServiceAdditionalCost>
<FreeShipping>true</FreeShipping>
</ShippingServiceOptions>
<InternationalShippingServiceOption>
<ShippingService>StandardInternational</ShippingService>
<ShippingServiceCost currencyID="EUR">0</ShippingServiceCost>
<ShippingServiceAdditionalCost currencyID="EUR">0</ShippingServiceAdditionalCost>
<ShippingServicePriority>1</ShippingServicePriority>
<ShipToLocation>Americas</ShipToLocation>
<ShipToLocation>Europe</ShipToLocation>
</InternationalShippingServiceOption>
<ShippingType>Flat</ShippingType>
<InsuranceDetails>
<InsuranceFee currencyID="EUR">0</InsuranceFee>
<InsuranceOption>NotOffered</InsuranceOption>
</InsuranceDetails>
<InternationalInsuranceDetails>
<InsuranceFee currencyID="EUR">0</InsuranceFee>
<InsuranceOption>NotOffered</InsuranceOption>
</InternationalInsuranceDetails>
</ShippingDetails>
<Site xmlns="urn:ebay:apis:eBLBaseComponents">US</Site>
<Storefront xmlns="urn:ebay:apis:eBLBaseComponents">
<StoreCategoryID>2947535016</StoreCategoryID>
<StoreCategory2ID>0</StoreCategory2ID>
</Storefront>
<DispatchTimeMax xmlns="urn:ebay:apis:eBLBaseComponents">4</DispatchTimeMax>
<ReturnPolicy xmlns="urn:ebay:apis:eBLBaseComponents">
<ReturnsAcceptedOption>ReturnsAccepted</ReturnsAcceptedOption>
<Description>Accepted</Description>
<ShippingCostPaidByOption>Buyer</ShippingCostPaidByOption>
</ReturnPolicy>
<ConditionID xmlns="urn:ebay:apis:eBLBaseComponents">1000</ConditionID>
</ItemType>
I would love to query the table on that field, for example to extract CategoryID field.
I tried everything I knew, like casting to ntext, removing utf-16, replacing it with utf-8, adding namespaces and stuff like that, but the result is always a NULL record.
Here is one of the queries I tried:
;WITH XMLNAMESPACES('urn:ebay:apis:eBLBaseComponents' AS ns,
'http://www.w3.org/2001/XMLSchema-instance' as xsi,
'http://www.w3.org/2001/XMLSchema' as xsd)
select CategoryVal = CONVERT(xml, [Template]).value('(/ItemType/PrimaryCategory/CategoryID)[1]', 'nvarchar(max)') FROM Templates where ID = 1
Thanks, Marco
with xmlnamespaces('urn:ebay:apis:eBLBaseComponents' as n)
select cast(Template as xml).value('(/ItemType/n:PrimaryCategory/n:CategoryID)[1]', 'nvarchar(max)')
from Templates
where ID = 1
You need to prefix the elements in your xpath expression.
I've done that once, but without the use of namespaces.
I had my input as varchar(max) (nvarchar should work too)
#Text AS varchar(MAX)
Then i used an XML type variable and the conversion was as simple as this:
DECLARE #XML XML
SELECT #XML = #Text
To query your CategoryID value you would use:
SELECT itemtype.item.value('(/ItemType/PrimaryCategory/CategoryID)[1]', 'nvarchar(max)')
FROM #XML.nodes('/ItemType') AS itemtype(item);

Resources