Sql server 在t-sql中解析Xml,使用XQuery选择器从根中的几个级别发出,并解析所选节点的值
我对解析Xml中的值非常陌生,希望具有一些XMLXQuery/XPATH知识的人能向我解释如何使用t-sql解析以下Xml中的某些值。我将包括我所做的代码尝试,以表明我不仅仅是要求别人为我做这件事 给定以下Soap Xml响应:Sql server 在t-sql中解析Xml,使用XQuery选择器从根中的几个级别发出,并解析所选节点的值,sql-server,xml,xpath,soap,xquery-sql,Sql Server,Xml,Xpath,Soap,Xquery Sql,我对解析Xml中的值非常陌生,希望具有一些XMLXQuery/XPATH知识的人能向我解释如何使用t-sql解析以下Xml中的某些值。我将包括我所做的代码尝试,以表明我不仅仅是要求别人为我做这件事 给定以下Soap Xml响应: <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:aah:remtp:schemas:P
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:aah:remtp:schemas:PlaceOrderResponse:1.00">
<SOAP-ENV:Body>
<PlaceOrderResponse xmlns="urn:aah:remtp:schemas:PlaceOrderResponse:1.00">
<StatusCode>0</StatusCode>
<TextReply>Successful</TextReply>
<PlaceOrderReplyMessage>
<TransmissionId>aac1e254-bc05-4d69-b04d-31d5fead314e</TransmissionId>
<ReplyOrder>
<TrackingId>aac1e254-bc05-4d69-b04d-31d5fead314e</TrackingId>
<CustomerAccount>A_TEST</CustomerAccount>
<CustomerOrder>aac1e254-bc05-4d69-b04d-31d5fead314e</CustomerOrder>
<ReplyGroup>
<LineNumber>1</LineNumber>
<ReplyItem>
<ReplyCode>0</ReplyCode>
<ReplyData>10</ReplyData>
<ReplyMsg>Successful</ReplyMsg>
</ReplyItem>
</ReplyGroup>
<ReplyGroup>
<LineNumber>2</LineNumber>
<ReplyItem>
<ReplyCode>0</ReplyCode>
<ReplyData>15</ReplyData>
<ReplyMsg>Successful</ReplyMsg>
</ReplyItem>
</ReplyGroup>
</ReplyOrder>
</PlaceOrderReplyMessage>
</PlaceOrderResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
一旦我对select进行了排序,就可以将replygroup解析为一个表变量,我认为这应该很容易
我尝试了以下方法:
DECLARE @XmlDocument XML
DECLARE @StatusCode VARCHAR(MAX)
DECLARE @TextReply VARCHAR(MAX)
DECLARE @CustomerOrder VARCHAR(MAX)
SELECT @XmlDocument = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:aah:remtp:schemas:PlaceOrderResponse:1.00">
<SOAP-ENV:Body>
<PlaceOrderResponse xmlns="urn:aah:remtp:schemas:PlaceOrderResponse:1.00">
<StatusCode>0</StatusCode>
<TextReply>Successful</TextReply>
<PlaceOrderReplyMessage>
<TransmissionId>aac1e254-bc05-4d69-b04d-31d5fead314e</TransmissionId>
<ReplyOrder>
<TrackingId>aac1e254-bc05-4d69-b04d-31d5fead314e</TrackingId>
<CustomerAccount>A_TEST</CustomerAccount>
<CustomerOrder>aac1e254-bc05-4d69-b04d-31d5fead314e</CustomerOrder>
<ReplyGroup>
<LineNumber>1</LineNumber>
<ReplyItem>
<ReplyCode>0</ReplyCode>
<ReplyData>10</ReplyData>
<ReplyMsg>Successful</ReplyMsg>
</ReplyItem>
</ReplyGroup>
<ReplyGroup>
<LineNumber>2</LineNumber>
<ReplyItem>
<ReplyCode>0</ReplyCode>
<ReplyData>15</ReplyData>
<ReplyMsg>Successful</ReplyMsg>
</ReplyItem>
</ReplyGroup>
</ReplyOrder>
</PlaceOrderReplyMessage>
</PlaceOrderResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>'
-- PlaceOrderResponse/StatusCode
SELECT @StatusCode = CONVERT(VARCHAR(MAX), @XmlDocument.query('/PlaceOrderResponse/StatusCode'))
-- PlaceOrderResponse/TextReply
SELECT @TextReply = CONVERT(VARCHAR(MAX), @XmlDocument.query('/PlaceOrderResponse/TextReply'))
-- PlaceOrderResponse/PlaceOrderReplyMessage/ReplyOrder/CustomerOrder
SELECT @CustomerOrder = CONVERT(VARCHAR(MAX), @XmlDocument.query('/PlaceOrderResponse/PlaceOrderReplyMessage/ReplyOrder'))
--SELECT @StatusCode As StatusCode, @TextReply As TextReply, @CustomerOrder As CustomerOrder
--INSERT INTO @ResponseLines(LineNumber, ReplyCode, ReplyData, ReplyMessage)
SELECT @XmlDocument.query('/PlaceOrderResponse/PlaceOrderReplyMessage/ReplyOrder/ReplyGroup')
不幸的是,在此之后所有变量都是空的,我想这是因为我没有从选择器中的根节点开始。此外,如果我删除两个soap信封节点和任何名称空间,则会使用实际节点而不是每个节点内的值填充值
如果有人能告诉我:
如何从节点而不是根节点开始查询Xml以获得正确的节点
如何解析节点内部的值我正在查看StatusCode、ReplyText、CustomerOrder。
如何将多个项目选择到表结构中。请注意,该元素在Xml树层次结构中的位置高于与其关联的元素。
您需要注意名称空间。请查看下面的操作方法 SQL SQL 2
…如何将多个项目选择到表结构中。。。。你需要编辑你的帖子,编辑XML结构,并澄清它的含义。这太棒了@Yitzhak Khabinsky我只需要研究如何扩展你的答案来检索ReplyGroup节点不幸的是,我发布的问题和XML片段只显示了一个,但可以有多个。但是谢谢你对我的问题的快速回答。我用可能的INSERT语句更新了答案。看看。@Yitshak-你太棒了。。。谢谢你。。。希望以后我能在我得到的其他XMl响应中使用这些示例——我相信会有很多
DECLARE @XmlDocument XML
DECLARE @StatusCode VARCHAR(MAX)
DECLARE @TextReply VARCHAR(MAX)
DECLARE @CustomerOrder VARCHAR(MAX)
SELECT @XmlDocument =
N'<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:aah:remtp:schemas:PlaceOrderResponse:1.00">
<SOAP-ENV:Body>
<PlaceOrderResponse xmlns="urn:aah:remtp:schemas:PlaceOrderResponse:1.00">
<StatusCode>0</StatusCode>
<TextReply>Successful</TextReply>
<PlaceOrderReplyMessage>
<TransmissionId>aac1e254-bc05-4d69-b04d-31d5fead314e</TransmissionId>
<ReplyOrder>
<TrackingId>aac1e254-bc05-4d69-b04d-31d5fead314e</TrackingId>
<CustomerAccount>A_TEST</CustomerAccount>
<CustomerOrder>aac1e254-bc05-4d69-b04d-31d5fead314e</CustomerOrder>
<ReplyGroup>
<LineNumber>1</LineNumber>
<ReplyItem>
<ReplyCode>0</ReplyCode>
<ReplyData>10</ReplyData>
<ReplyMsg>Successful</ReplyMsg>
</ReplyItem>
</ReplyGroup>
</ReplyOrder>
</PlaceOrderReplyMessage>
</PlaceOrderResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
;WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS [SOAP-ENV]
,'urn:aah:remtp:schemas:PlaceOrderResponse:1.00' AS ns2)
SELECT @StatusCode = c.value('(ns2:StatusCode/text())[1]','INT')
, @TextReply = c.value('(ns2:TextReply/text())[1]','VARCHAR(100)')
, @CustomerOrder = c.value('(ns2:PlaceOrderReplyMessage/ns2:ReplyOrder/ns2:CustomerOrder/text())[1]','VARCHAR(100)')
FROM @XmlDocument.nodes('/SOAP-ENV:Envelope/SOAP-ENV:Body/ns2:PlaceOrderResponse') AS t(c);
-- test
SELECT @StatusCode AS StatusCode
, @TextReply AS TextReply
, @CustomerOrder AS CustomerOrder;
+------------+------------+--------------------------------------+
| StatusCode | TextReply | CustomerOrder |
+------------+------------+--------------------------------------+
| 0 | Successful | aac1e254-bc05-4d69-b04d-31d5fead314e |
+------------+------------+--------------------------------------+
;WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS [SOAP-ENV]
, DEFAULT 'urn:aah:remtp:schemas:PlaceOrderResponse:1.00')
--INSERT INTO @ResponseLines(LineNumber, ReplyCode, ReplyData, ReplyMessage)
SELECT c.value('(LineNumber/text())[1]','INT')
, c.value('(ReplyItem/ReplyCode/text())[1]','VARCHAR(100)')
, c.value('(ReplyItem/ReplyData/text())[1]','VARCHAR(100)')
, c.value('(ReplyItem/ReplyMsg/text())[1]','VARCHAR(100)')
FROM @XmlDocument.nodes('/SOAP-ENV:Envelope/SOAP-ENV:Body/PlaceOrderResponse/PlaceOrderReplyMessage/ReplyOrder/ReplyGroup') AS t(c);