En utilisant MS SQL Server, j'ai des données dans un champ XML (appelé XML ), qui est structuré comme ceci:
<Transaction01> <TransactionSetPurpose>Insert</TransactionSetPurpose> <POHeader> <PO_NBR>LG40016181</PO_NBR> </POHeader> </Transaction01>
J'essaie de créer une requête SQL pour récupérer une autre colonne appelée SubmittedDate, avec le PO_NBR de ce champ XML. Étant nouveau pour XPath, j'ai lu de nombreux exemples et essayé à la fois la requête et la valeur , mais je n'ai pas encore réussi. Par exemple:
SELECT SubmittedDate, XML.query('data(/POHeader/PO_NBR)') as PO_NBR FROM SubmitXML
Cela me donne juste une colonne vide. Après avoir obtenu un test de travail de Quassnoi, j'ai travaillé de son XML vers le mien, et j'ai découvert que le problème était les attributes xmlns et xmlns: i dans le nœud racine:
<Transaction01 xmlns="http://services.iesltd.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
Alors, comment puis-je contourner cela?
SELECT SubmittedDate, XML.query('data(/Transaction01/POHeader/PO_NBR)') as PO_NBR FROM SubmitXML
Vous XPath
origine, /POHeader/PO_NBR
, supposé que POHeader
est le nœud racine (qui ne l'est pas).
Un exemple de requête à vérifier:
DECLARE @myxml XML SET @myxml = ' <Transaction01> <TransactionSetPurpose>Insert</TransactionSetPurpose> <POHeader> <PO_NBR>LG40016181</PO_NBR> </POHeader> </Transaction01>' SELECT @myxml.query('data(/Transaction01/POHeader/PO_NBR)')
Si Transaction01
n'est pas toujours le noeud racine (ce qui n'est pas une bonne chose), utilisez ceci:
SELECT SubmittedDate, XML.query('data(/*/POHeader/PO_NBR)') as PO_NBR FROM SubmitXML
Généralement, le schéma XML
suppose que les noms des points sont corrigés et que les parties variables vont aux données des nœuds et des attributes plutôt que dans leurs noms, comme ceci:
<Transaction id='01'> <TransactionSetPurpose>Insert</TransactionSetPurpose> <POHeader> <PO_NBR>LG40016181</PO_NBR> </POHeader> </Transaction>
Mettre à jour:
Vous devez déclarer les namespaces à l'aide de WITH XMLNAMESPACES
:
DECLARE @myxml XML SET @myxml = ' <Transaction01 xmlns="http://services.iesltd.com/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <TransactionSetPurpose>Insert</TransactionSetPurpose> <POHeader> <PO_NBR>LG40016181</PO_NBR> </POHeader> </Transaction01>' ; WITH XMLNAMESPACES ( 'http://services.iesltd.com/' AS m ) SELECT @myxml.query ( 'data(/*/m:POHeader/m:PO_NBR)' )
Mise à jour 2:
Trier:
; WITH XMLNAMESPACES ( 'http://services.iesltd.com/' AS m ) SELECT SubmittedDate, XML.value('(/*/m:POHeader/m:PO_NBR)[1]', 'NVARCHAR(200)') AS po_nbr FROM SubmitXML ORDER BY po_nbr
Si vous voulez éviter le encoding en dur de Transaction01, vous pouvez essayer ceci:
SELECT SubmittedDate, XML.query('data(//POHeader/PO_NBR)') as PO_NBR FROM SubmitXML
PAR EXEMPLE:
CREATE TABLE #TEMP (XMLTEXT XML) INSERT INTO #TEMP SELECT '<Transaction01> <TransactionSetPurpose>Insert</TransactionSetPurpose> <POHeader> <PO_NBR>LG40016181</PO_NBR> </POHeader> </Transaction01> ' SELECT XMLTEXT.query('data(//POHeader/PO_NBR)') as PO_NBR FROM #TEMP