I have the following XML and code and can pull back the AccountNumber and Status. I also need to pull back...
The ID property of the MFRRequest
Several elements from the CaseInformation node
I am not sure how to get the ID property and I'm wondering... can I get all of this information (from multiple nodes) back in the same query?
Thank you!
DECLARE #doc xml
SET #doc =
'<?xml version="1.0" encoding="UTF-8"?>
<p:OrderRequest xmlns:p="http://XXX.Schemas.OrderRequest/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://XXX.Schemas.OrderRequest/2 OrderRequestV2.xsd ">
<p:Header>
<p:SCRARequestCount>0</p:SCRARequestCount>
<p:MFRRequestCount>1</p:MFRRequestCount>
<p:FileCreatedAt>2001-12-31T12:00:00</p:FileCreatedAt>
<p:RequestFileName>p:RequestFileName</p:RequestFileName>
</p:Header>
<p:RequestItems>
<p:MFRRequest id="1" priority="">
<p:AccountNumber>9999999</p:AccountNumber>
<Status>Initial</Status>
<p:CaseInformation>
<ReferralDate>2011-01-01</ReferralDate>
<LoanType>1A</LoanType>
<ARM>Yes</ARM>
<InvestorNumber>InvestorNumber</InvestorNumber>
<PropertyAddress>PropertyAddress</PropertyAddress>
<PrivateLabel>Yes</PrivateLabel>
<CaseNumber>01-11111/AK/</CaseNumber>
<SuspenseBalance>9999.00</SuspenseBalance>
<TitleOrderedDate>2011-09-01</TitleOrderedDate>
<TotalMonthlyPayment>876.99</TotalMonthlyPayment>
</p:CaseInformation>
</p:MFRRequest>
</p:RequestItems>
</p:OrderRequest>'
;WITH XMLNAMESPACES('http://XXX.Schemas.OrderRequest/2' AS p)
SELECT
Y.i.value('Status[1]', 'varchar(10)') AS Status ,
Y.i.value('p:AccountNumber[1]', 'varchar(10)') AS AccountNumber
FROM #doc.nodes('/p:OrderRequest/p:RequestItems/p:MFRRequest') AS Y(i)
Try something like this:
;WITH XMLNAMESPACES('http://XXX.Schemas.OrderRequest/2' AS p)
SELECT
MFRRequestID = Y.i.value('(#id)[1]', 'int'),
RequestStatus = Y.i.value('Status[1]', 'varchar(10)') ,
AccountNumber = Y.i.value('p:AccountNumber[1]', 'varchar(10)'),
ReferralDate = CIF.value('(ReferralDate)[1]', 'varchar(25)'),
CaseInfoType = CIF.value('(Type)[1]', 'varchar(25)')
FROM
#doc.nodes('/p:OrderRequest/p:RequestItems/p:MFRRequest') AS Y(i)
CROSS APPLY
i.nodes('p:CaseInformation') AS Tbl(CIF)
Basically, once you have the <p:MFRRequest> XML element in your Y(i) pseudo-table, you can then again use a second call to .nodes() to get the (possibly multiple) <p:CaseInfomration> nodes and use .value() calls on this new second pseudo-table to extract single bits of information from it.
Related
I want to get the values Total and TipoDeComprobante of the tag name cfdi:Comprobante, currently in my table the column where the XML is stored is of type image so I do the following query to get the value of the XML, I tried to do some substring but I have not been successful, could you help me?
Query to obtain the xml
select cast(cast(xml as varbinary(max)) as varchar(max)) as column_name
from [tb_cfdi]
where uuid = 'f425cd6d-ed30-4a0d-8135-8dc7229b79ff' ;
Result
<?xml version="1.0" encoding="utf-8"?>
<cfdi:Comprobante xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" Version="3.3" Serie="PRUEBAS-SEBASTIAN" Folio="SEBASTIANCANCELACIONSD-27" Fecha="2022-05-23T18:42:38" Sello="dUxav04E0XcbOhMsXjXDlWbFlZdcXqOk/R8DHLd3TILZ7gg5/aw+T+gI9yMLpVLvPkeEm5+A++QWHi0I/26TVTlsx6ejFWxXTEdewmarCuSrRO24CSFPz2dLX6ojy5Eg6QGTV0EQiS3LRtLsnTyqXH2QE7Ne+Y7cqXXEcXWZ63AIAkkWY4U9uQu1/3F0jiHFfMCf4lBuSgDQ8c8LniBKoAsFoTySZmyhJv4h2koz1bE0Yl6Rvrr0NNlmYSH+SGqbkYVsYKM9fbHIDJbNXosRqIGlugOlLIT2499j3gQfTn7d3sdQLtVqn4tcqaDGx2Du2dm1XFJRwT7aB62btNVW1Q==" FormaPago="99" NoCertificado="30001000000400002325" Certificado="MIIFdjCCA16gAwIBAgIUMzAwMDEwMDAwMDA0MDAwMDIzMjUwDQYJKoZIhvcNAQELBQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFETUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9yaXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0wGwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWRpejEOMAwGA1UEEQwFMDYzNzAxCzAJBgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhDT1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3BvbnNhYmxlOiBBQ0RNQS1TQVQwHhcNMTkwNTI5MTgwNDM0WhcNMjMwNTI5MTgwNDM0WjCBnTEYMBYGA1UEAxMPWEFJTUUgV0VJUiBST0pPMRgwFgYDVQQpEw9YQUlNRSBXRUlSIFJPSk8xGDAWBgNVBAoTD1hBSU1FIFdFSVIgUk9KTzEWMBQGA1UELRMNV0VSWDYzMTAxNlMzMDEbMBkGA1UEBRMSV0VSWDYzMTAxNkhKQ1JKTTA4MRgwFgYDVQQLEw9YQUlNRSBXRUlSIFJPSk8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwSjRVq5oohPioYAWcUoxVAvudA2MqKDBwX/GukHngSLtqMZ6b5I/JIhnDyqauugRYaQRW7FH+jxoijWR340zYhhgea2HYfE7WDUQNlraqtZ9re+OX5RX3KQA4sPw3pcVMcUbiCDr3vVBVaWtEaAaIsh1LxPgwWQ2egFarmMkHHEUTLkISe2WqrOFKd3PJ9vgj6h4+EF0+C3qKt55pRsLTh9r828Mo7E7AROaSJK5XG/x/5xE5sYyV2kqCFIs11xdfTn00FEmUgK+caW2lKYj9KqSuKu8UyJcOdrk2LhZlHhJO16LXrTsItJZPhJJ03FYi4+w0TNY7Eg87BC38nz5NAgMBAAGjHTAbMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgbAMA0GCSqGSIb3DQEBCwUAA4ICAQCF9+3Q0bUnTVREjva/R2fNjnoksrHUwviYkRGOTfQeJbOF76gcz1aqkMpuhk9uvbnxLtNXTrpJZaW/9f7aVSIEP7x9u5XcikC5NOw4g0r/8uhCbeF41yIIAdCufg22YSMyfzAtzmW96tO1Q/PYaloCpEjtiWcufSVpmOFP/oQszWP8g4z3XG/DDPrhvO8Lk2ZghfsCuhi4KvNnBUZOn7Vm4kadt3QIfb4+gCkMn4uA0GLCIGWH/yvF4dQdc6if1ev/1FtGHe7CP54e+PuOm8JjBFkzfXNiXIZq8NdnUNnwEUl+zeXm1H4qog4WC/sceOtUVbRQy9sUYeX13+1yNtRQxGMebD+tsTvY4xtwqjMw7TeOcLe27rJsPAV62vFIsL8HlDuYNC3mZJzg40pxlPjqt+xhQAXM3MOYfQq+89t+4Cr4xaglLZ2NHAY7MZk0SN62c7f8yL4EA81Yg6LeIgDei3ZiNXcLeFKtCvDwbuIoD9Oqane7QH/jfOrIlRRxHeGb7Nmob+PXe7BN9VYqQ0/dOSPRKol0DLRRpwA/2Qn8nbq3nl0ZCbJYfC/8psh/hUAkPUXPRH2+JoWORVzKjBDZ5FaLxV9t5q3rV/YeMVuS9qqzjs1/RvM5aa4cLh3Cc6S1vojBy1QitiGwRxzy4SHkF69dyxnQbyUVOMkuBiMyWg==" SubTotal="200.0" Moneda="AMD" TipoCambio="1" Total="200.16" TipoDeComprobante="I" MetodoPago="PPD" LugarExpedicion="20000" xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd">
<cfdi:Emisor Rfc="WERX631016S30" Nombre="XAIME WEIR ROJO" RegimenFiscal="605"/>
<cfdi:Receptor Rfc="EKU9003173C9" Nombre="ESCUELA KEMPER URGATE" UsoCFDI="G03"/>
<cfdi:Conceptos>
<cfdi:Concepto ClaveProdServ="50211503" Cantidad="1" ClaveUnidad="H87" Unidad="Pieza" Descripcion="Cigarros" ValorUnitario="200.0" Importe="200.0">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="1" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="0.16"/>
</cfdi:Traslados>
<cfdi:Retenciones>
<cfdi:Retencion Base="1" Impuesto="001" TipoFactor="Tasa" TasaOCuota="0.100000" Importe="0.00"/>
<cfdi:Retencion Base="1" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.106666" Importe="0.00"/>
</cfdi:Retenciones>
</cfdi:Impuestos>
</cfdi:Concepto>
</cfdi:Conceptos>
<cfdi:Impuestos TotalImpuestosRetenidos="0.00" TotalImpuestosTrasladados="0.16">
<cfdi:Retenciones>
<cfdi:Retencion Impuesto="001" Importe="0.00"/>
<cfdi:Retencion Impuesto="002" Importe="0.00"/>
</cfdi:Retenciones>
<cfdi:Traslados>
<cfdi:Traslado Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="0.16"/>
</cfdi:Traslados>
</cfdi:Impuestos>
<cfdi:Complemento>
<tfd:TimbreFiscalDigital xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigitalv11.xsd" Version="1.1" UUID="f425cd6d-ed30-4a0d-8135-8dc7229b79ff" FechaTimbrado="2022-05-23T18:42:50" RfcProvCertif="SPR190613I52" SelloCFD="dUxav04E0XcbOhMsXjXDlWbFlZdcXqOk/R8DHLd3TILZ7gg5/aw+T+gI9yMLpVLvPkeEm5+A++QWHi0I/26TVTlsx6ejFWxXTEdewmarCuSrRO24CSFPz2dLX6ojy5Eg6QGTV0EQiS3LRtLsnTyqXH2QE7Ne+Y7cqXXEcXWZ63AIAkkWY4U9uQu1/3F0jiHFfMCf4lBuSgDQ8c8LniBKoAsFoTySZmyhJv4h2koz1bE0Yl6Rvrr0NNlmYSH+SGqbkYVsYKM9fbHIDJbNXosRqIGlugOlLIT2499j3gQfTn7d3sdQLtVqn4tcqaDGx2Du2dm1XFJRwT7aB62btNVW1Q==" NoCertificadoSAT="30001000000400002495" SelloSAT="gfFwozFJpvd1zpwvQPCkUWBfBG72/bn1+0CwrgnPx466uzjrL0RMsoSRHplN4dpTiqfAT/+bhGA8KjDDG6p+3RvlVxx1dmUIVffRcTv2Jd1D+zZQRlt3RkHuANjCtOSVZKiW181WUyqzmH7ehL+S7lyBL7odWswW4CGr5UPrMBFaSDSR6K+3aw2nd7SJce/2+rWN4szUIE4YlUS2whPLznlOdsRrSSy6OHJLkptSJaGn86F8bcp46Idz4lDNkI1G72lN3Kmat5cTrA8f9VTj8BfCzlmKdXg/jD7/1vOHm4mF3qmaLUym84Yj370ax7dGxYb4KoNLAxuYRJjJq1wkbw==" xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</cfdi:Complemento>
</cfdi:Comprobante>
You can also use #marc_s's answer with your existing data type, although I agree the table should be changed if at all possible
WITH XMLNAMESPACES('http://www.sat.gob.mx/cfd/3' AS cfdi)
SELECT
Total = xc.value('#Total' , 'decimal(20,2)'),
TipoDeComprobante = xc.value('#TipoDeComprobante', 'varchar(20)')
FROM tb_cfdi c
CROSS APPLY (
SELECT CAST(CAST(xml AS varbinary(max)) AS xml) AS data
) v
CROSS APPLY v.data.nodes('/cfdi:Comprobante') AS xt(xc)
WHERE c.uuid = 'f425cd6d-ed30-4a0d-8135-8dc7229b79ff';
First of all - get rid of that Image datatype! It's deprecated and will be removed in a future version of SQL Server.
Image is also a binary type - why use that to store textual information like XML ?? Makes no sense.... use XML datatype for best results.
Once you do have your XML in a T-SQL variable #data XML, you can then use this XQuery to get the values you're interested in:
WITH XMLNAMESPACES('http://www.sat.gob.mx/cfd/3' AS cfdi)
SELECT
Total = xc.value('#Total', 'decimal(20,2)'),
TipoDeComprobante = xc.value('#TipoDeComprobante', 'varchar(20)')
FROM
#data.nodes('(/cfdi:Comprobante)') AS XT(XC)
I have an XML in SQL table column. I need to decode this xml and get value of particular nodes. Find my XML below
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns:createTransactionResponse
xmlns:impl="http://office/work/services/service1"
xmlns:ns="http://www.regfrez.com/schemas/service1_V2/SharedResources/XMLSchema/Schema.xsd"
xmlns:tns="http://www.erdeftq.ae/Activematrix/ESB/service1/1_0">
<transactionResponse>
<transaction-info>
<registrationId>R1234</registrationId>
<trialId>T12345</trialId>
<transactionId>12345</transactionId>
<transactionDate>27-02-2020:08:47</transactionDate>
<status>Confirmed</status>
</transaction-info>
</transactionResponse>
</ns:createTransactionResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I need the values of nodes: registrationId, transactionId and status and I tried this but couldn't succeed as i got empty value as result:
DECLARE #xml XML
SET #xml = 'XML here'
SELECT T.C.value('#status', 'nvarchar(100)') FROM #xml.nodes('createTransactionResponse/transactionResponse/transaction-info/status') T(C)
SELECT T.C.value('#trans', 'nvarchar(100)') FROM #xml.nodes('createTransactionResponse/transactionResponse/transaction-info/transactionId') T(C)
SELECT T.C.value('#id', 'nvarchar(100)') FROM #xml.nodes('createTransactionResponse/transactionResponse/transaction-info/registrationId') T(C)
Any help/correction would be appreciated
Your own attempt is ignoring the namespaces and does not specify the full XPath.
Try one of these approaches:
Your XML:
DECLARE #xml XML
SET #xml = '<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns:createTransactionResponse
xmlns:impl="http://office/work/services/service1"
xmlns:ns="http://www.regfrez.com/schemas/service1_V2/SharedResources/XMLSchema/Schema.xsd"
xmlns:tns="http://www.erdeftq.ae/Activematrix/ESB/service1/1_0">
<transactionResponse>
<transaction-info>
<registrationId>R1234</registrationId>
<trialId>T12345</trialId>
<transactionId>12345</transactionId>
<transactionDate>27-02-2020:08:47</transactionDate>
<status>Confirmed</status>
</transaction-info>
</transactionResponse>
</ns:createTransactionResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
--This is the most explicit (which is always a best way):
WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS n1
,'http://www.regfrez.com/schemas/service1_V2/SharedResources/XMLSchema/Schema.xsd' AS n2)
SELECT #xml.value('(/n1:Envelope/n1:Body/n2:createTransactionResponse/transactionResponse/transaction-info/registrationId/text())[1]','nvarchar(max)') AS RegistrationId
,#xml.value('(/n1:Envelope/n1:Body/n2:createTransactionResponse/transactionResponse/transaction-info/transactionId/text())[1]','nvarchar(max)') AS TransactionId
,#xml.value('(/n1:Envelope/n1:Body/n2:createTransactionResponse/transactionResponse/transaction-info/status/text())[1]','nvarchar(max)') AS [Status];
--This will avoid some repeated XPath, but .nodes() produces quite some overhead:
WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS n1
,'http://www.regfrez.com/schemas/service1_V2/SharedResources/XMLSchema/Schema.xsd' AS n2)
SELECT ti.value('(registrationId/text())[1]','nvarchar(max)') AS RegistrationId
,ti.value('(transactionId/text())[1]','nvarchar(max)') AS TransactionId
,ti.value('(status/text())[1]','nvarchar(max)') AS [Status]
FROM #xml.nodes('/n1:Envelope/n1:Body/n2:createTransactionResponse/transactionResponse/transaction-info') A(ti);
--And this is for lazy people :-)
SELECT #xml.value('(//*:registrationId)[1]','nvarchar(max)') AS RegistrationId
,#xml.value('(//*:transactionId)[1]','nvarchar(max)') AS TransactionId
,#xml.value('(//*:status)[1]','nvarchar(max)') AS [Status];
Hint: The last one (for lazy people) uses the deep search (with //) and uses a wildcard for the namespace. This is very dangerous if the elements might occur more than once within your XML.
The XML you have is pretty complex. You have multiple namespaces, with different nodes using different ones. This means you need to use WITH XMLNAMESPACES to declare all these.
Then you need to use nodes to navigate the to needed node, prefixing them with the appropriate namespaces, till you get to transaction-info. Then you use use value to get the information.
#Status isn't what you're after here, that's for is you have something like <node status=1\>, you need to get the text() value of the node.
This results in the below:
DECLARE #X xml = '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns:createTransactionResponse
xmlns:impl="http://traffic2/traffic/services/service1"
xmlns:ns="http://www.regfrez.com/schemas/service1_V2/SharedResources/XMLSchema/Schema.xsd"
xmlns:tns="http://www.abc.ae/Activematrix/ESB/service1/1_0">
<transactionResponse>
<transaction-info>
<registrationId>R1234</registrationId>
<trialId>T12345</trialId>
<transactionId>12345</transactionId>
<transactionDate>27-02-2020:08:47</transactionDate>
<status>Confirmed</status>
</transaction-info>
</transactionResponse>
</ns:createTransactionResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
WITH XMLNAMESPACES ('http://schemas.xmlsoap.org/soap/envelope/' AS [SOAP-ENV],
'http://traffic2/traffic/services/service1' AS impl, --YOu don't use this in the XML, but incldued anyway, for completeness
'http://www.regfrez.com/schemas/service1_V2/SharedResources/XMLSchema/Schema.xsd' AS ns,
'http://www.abc.ae/Activematrix/ESB/service1/1_0' AS tns) --YOu don't use this in the XML, but incldued anyway, for completeness
SELECT ti.value('(status/text())[1]','varchar(10)') AS [Status],
ti.value('(transactionId/text())[1]','int') AS Trans,
ti.value('(registrationId/text())[1]','varchar(10)') AS ID
FROM #X.nodes('SOAP-ENV:Envelope/SOAP-ENV:Body/ns:createTransactionResponse/transactionResponse/transaction-info') N(ti);
I've found several pieces of information online about this but I can't get it working for the life of me.
This is the XML I have:
I need to extract the ID & Name value for each node. There are a lot.
I tried to do this but it returns NULL:
select [xml].value('(/Alter/Object/ObjectDefinition/MeasureGroup/Partitions/Partition/ID)[1]', 'varchar(max)')
from test_xml
I understand the above would return only 1 record. My question is, how do I return all records?
Here's the XML text (stripped down version):
<Alter xmlns="http://schemas.microsoft.com/analysisservices/2003/engine" AllowCreate="true" ObjectExpansion="ExpandFull">
<ObjectDefinition>
<MeasureGroup xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>ts_homevideo_sum_20140430_76091ba1-3a51-45bf-a767-f9f3de7eeabe</ID>
<Name>table_1</Name>
<StorageMode valuens="ddl200_200">InMemory</StorageMode>
<ProcessingMode>Regular</ProcessingMode>
<Partitions>
<Partition>
<ID>123</ID>
<Name>2012</Name>
</Partition>
<Partition>
<ID>456</ID>
<Name>2013</Name>
</Partition>
</Partitions>
</MeasureGroup>
</ObjectDefinition>
</Alter>
You need something like this:
DECLARE #MyTable TABLE (ID INT NOT NULL, XmlData XML)
INSERT INTO #MyTable (ID, XmlData)
VALUES (1, '<Alter xmlns="http://schemas.microsoft.com/analysisservices/2003/engine" AllowCreate="true" ObjectExpansion="ExpandFull">
<ObjectDefinition>
<MeasureGroup xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>ts_homevideo_sum_20140430_76091ba1-3a51-45bf-a767-f9f3de7eeabe</ID>
<Name>table_1</Name>
<StorageMode valuens="ddl200_200">InMemory</StorageMode>
<ProcessingMode>Regular</ProcessingMode>
<Partitions>
<Partition>
<ID>123</ID>
<Name>2012</Name>
</Partition>
<Partition>
<ID>456</ID>
<Name>2013</Name>
</Partition>
</Partitions>
</MeasureGroup>
</ObjectDefinition>
</Alter>')
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.microsoft.com/analysisservices/2003/engine')
SELECT
tbl.ID,
MeasureGroupID = xc.value('(ID)[1]', 'varchar(200)'),
MeasureGroupName = xc.value('(Name)[1]', 'varchar(200)'),
PartitionID = xp.value('(ID)[1]', 'varchar(200)'),
PartitionName = xp.value('(Name)[1]', 'varchar(200)')
FROM
#MyTable tbl
CROSS APPLY
tbl.XmlData.nodes('/Alter/ObjectDefinition/MeasureGroup') AS XT(XC)
CROSS APPLY
XC.nodes('Partitions/Partition') AS XT2(XP)
WHERE
ID = 1
First of all, you must respect and include the default XML namespace defined in the root of your XML document.
Next, you need to do a nested call to .nodes() to get all <MeasureGroup> and all contained <Partition> nodes, so that you can reach into those XML fragments and extract the ID and Name from them.
This should then result in something like this as output:
I have a XML in Source Table. I need to parse this XML to 3 different tables which has Parent Child relationship. I can do this in C# but currently for this i need to implement it at SQL server side.
The sample xml looks like:
<ROWSET>
<ROW>
<HEADER_ID>5001507</HEADER_ID>
<ORDER_NUMBER>42678548</ORDER_NUMBER>
<CUST_PO_NUMBER>LSWQWE1</CUST_PO_NUMBER>
<CUSTOMER_NUMBER>38087</CUSTOMER_NUMBER>
<CUSTOMER_NAME>UNIVERSE SELLER</CUSTOMER_NAME>
<LINE>
<LINE_ROW>
<HEADER_ID>5001507</HEADER_ID>
<LINE_ID>12532839</LINE_ID>
<LINE_NUMBER>1</LINE_NUMBER>
<ITEM_NUMBER>STAGEPAS 600I-CA</ITEM_NUMBER>
<ORDER_QUANTITY>5</ORDER_QUANTITY>
</LINE_ROW>
<LINE_ROW>
<HEADER_ID>5001507</HEADER_ID>
<LINE_ID>12532901</LINE_ID>
<LINE_NUMBER>3</LINE_NUMBER>
<ITEM_NUMBER>CD-C600 RK</ITEM_NUMBER>
<ORDER_QUANTITY>6</ORDER_QUANTITY>
</LINE_ROW>
<LINE_ROW>
<HEADER_ID>5001507</HEADER_ID>
<LINE_ID>12532902</LINE_ID>
<LINE_NUMBER>4</LINE_NUMBER>
<ITEM_NUMBER>CD-S300 RK</ITEM_NUMBER>
<ORDER_QUANTITY>8</ORDER_QUANTITY>
</LINE_ROW>
</LINE>
<PRCADJ>
<PRCADJ_ROW>
<PRICE_ADJUSTMENT_ID>43095064</PRICE_ADJUSTMENT_ID>
<HEADER_ID>5001507</HEADER_ID>
<LINE_ID>12532839</LINE_ID>
<ADJUSTED_AMOUNT>-126</ADJUSTED_AMOUNT>
</PRCADJ_ROW>
<PRCADJ_ROW>
<PRICE_ADJUSTMENT_ID>43095068</PRICE_ADJUSTMENT_ID>
<HEADER_ID>5001507</HEADER_ID>
<LINE_ID>12532840</LINE_ID>
<ADJUSTED_AMOUNT>-96.6</ADJUSTED_AMOUNT>
</PRCADJ_ROW>
</PRCADJ>
</ROW>
</ROWSET>
The issue is the Parent can have multiple child and each child can multiple sub child. How can i write query to transfer this into Sql Server 2005
You need to use three CROSS APPLY operators to break up the "list of XML elements" into separate pseudo tables of XML rows, so you can access their properties - something like this:
SELECT
HeaderID = XCRow.value('(HEADER_ID)[1]', 'int'),
OrderNumber = XCRow.value('(ORDER_NUMBER)[1]', 'int'),
LineHeaderID = XCLine.value('(HEADER_ID)[1]', 'int'),
LineID = XCLine.value('(LINE_ID)[1]', 'int'),
LineNumber = XCLine.value('(LINE_NUMBER)[1]', 'int'),
PriceAdjustmentID = XCPrc.value('(PRICE_ADJUSTMENT_ID)[1]', 'int'),
AdjustedAmount = XCPrc.value('(ADJUSTED_AMOUNT)[1]', 'decimal(20,4)')
FROM
dbo.YourTableNameHere
CROSS APPLY
Data.nodes('/ROWSET/ROW') AS XTRow(XCRow)
CROSS APPLY
XCRow.nodes('LINE/LINE_ROW') AS XTLine(XCLine)
CROSS APPLY
XCRow.nodes('PRCADJ/PRCADJ_ROW') AS XTPrc(XCPrc)
With this, the first CROSS APPLY will handle all the elements that are found directly under <ROWSET> / <ROW> (the header information), the second one will enumerate all instances of <LINE> / <LINE_ROW> below that header element, and the third CROSS APPLY handles the <PRCADJ> / <PRCADJ_ROW> elements, also below the header.
You might need to tweak the outputs a bit - and I only picked two or three of the possible values - extend and adapt to your own needs! But this should show you the basic mechanism - the .nodes() method returns a "pseudo table" of XML fragments, one for each match of the XPath expression you define.
you can do some thing like this. using cross apply you will get node elements and then extract the value using value clause. you need to specify the column type i.e int or varchar etc.
The result can then be inserted using insert into select query.
insert into Table1 values ( header_id, order_number, cust_po_number)
select R.value('(HEADER_ID)[1]', 'int') As header_id,
R.value('(ORDER_NUMBER)[1]', 'int') as order_number,
R.value('(CUST_PO_NUMBER)[1]', 'varchar(256)') as cust_po_number
from table
cross apply XMLdata.nodes('/ROWSET/ROW') AS P(R)
insert into Table2 values ( header_id, line_id, line_number)
select R.value('(HEADER_ID)[1]', 'int') As header_id,
R.value('(LINE_ID)[1]', 'int') as line_id,
R.value('(LINE_NUMBER)[1]', 'int') as line_number
from table
cross apply XMLdata.nodes('/ROWSET/ROW/LINE/LINE_ROW') AS P(R)
Can anybody please help me with the below xml. I need extract all the xml values like below.
AwarYear Comments FieldCode FieldNumber Key Value
AY2013-14 AAI: Adjusted Available Income AAI 306 Blank None Calculated
Here is the sample XML.
<SchemaType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/process">
<AwardYear>AY2013_14</AwardYear>
<Fields>
<FieldSchema>
<Comments>AAI: Adjusted Available Income</Comments>
<DbLocation>IsirData</DbLocation>
<FieldCode>AAI</FieldCode>
<FieldNumber>306</FieldNumber>
<ReportDisplay>Data</ReportDisplay>
<ValidContent>
<ValidValueContent xmlns:d5p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d5p1:KeyValueOfstringstring>
<d5p1:Key>Blank</d5p1:Key>
<d5p1:Value>None calculated</d5p1:Value>
</d5p1:KeyValueOfstringstring>
</ValidValueContent>
</ValidContent>
</FieldSchema>
</Fields>
</SchemaType>
Please do the need full. Thanks in advance.
Assuming you have your XML in a table inside an XML column like this:
DECLARE #XmlTable TABLE (ID INT NOT NULL, XMLDATA XML)
INSERT INTO #XmlTable VALUES(1, '<SchemaType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/process">
<AwardYear>AY2013_14</AwardYear>
<Fields>
<FieldSchema>
<Comments>AAI: Adjusted Available Income</Comments>
<DbLocation>IsirData</DbLocation>
<FieldCode>AAI</FieldCode>
<FieldNumber>306</FieldNumber>
<ReportDisplay>Data</ReportDisplay>
<ValidContent>
<ValidValueContent xmlns:d5p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d5p1:KeyValueOfstringstring>
<d5p1:Key>Blank</d5p1:Key>
<d5p1:Value>None calculated</d5p1:Value>
</d5p1:KeyValueOfstringstring>
</ValidValueContent>
</ValidContent>
</FieldSchema>
</Fields>
</SchemaType>')
then you can use this T-SQL statement to fetch the values:
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/process',
'http://schemas.microsoft.com/2003/10/Serialization/Arrays' AS ns1)
SELECT
AwardYear = XmlData.value('(SchemaType/AwardYear)[1]', 'varchar(25)'),
Comments = XmlData.value('(SchemaType/Fields/FieldSchema/Comments)[1]', 'varchar(50)'),
FieldCode = XmlData.value('(SchemaType/Fields/FieldSchema/FieldCode)[1]', 'varchar(10)'),
FieldNumber = XmlData.value('(SchemaType/Fields/FieldSchema/FieldNumber)[1]', 'int'),
[Key] = XmlData.value('(SchemaType/Fields/FieldSchema/ValidContent/ValidValueContent/ns1:KeyValueOfstringstring/ns1:Key)[1]', 'varchar(10)'),
[Value] = XmlData.value('(SchemaType/Fields/FieldSchema/ValidContent/ValidValueContent/ns1:KeyValueOfstringstring/ns1:Value)[1]', 'varchar(10)')
FROM
#XmlTable
I defined the top-level XML namespace as the "default" namespace (that doesn't need to be referenced all over the place), and the second namespace deep inside your structure is defined explicitly with a separate XML namespace prefix.