问题描述
我对解析Xml中的值非常陌生,希望有人对Xml(XQUERY / XPATH)有所了解,可以向我解释如何使用t-sql从以下Xml中解析某些值。我将包括为证明我不只是要求某人为我而做的代码尝试。
给出以下Soap Xml响应:
<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>
然后将ReplyGroups解析为Table变量(一旦我对选择进行了排序,那应该很容易-我认为)。
我尝试了以下操作:
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')
不幸的是,此后所有变量都是空的,我认为这是因为我不是从选择器的根节点开始的。另外,如果我删除了两个肥皂信封节点和任何命名空间,则将填充值,但填充的是实际节点,而不是每个节点内部的值。
如果有人可以告诉我,我将不胜感激:
- 如何从
<PlaceOrderResponse>
节点而不是根节点开始查询Xml以获取正确的节点 - 如何从我正在查看的
(StatusCode,ReplyText,CustomerOrder)
节点内部解析值。 - 如何将多个
<ReplyGroup>
项目选择到一个表格结构中。请注意,在Xml树层次结构中,<LineNumber>
元素比与其关联的<ReplyItem>
高。
解决方法
您需要照顾名称空间。在下面查看操作方法。
SQL
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 |
+------------+------------+--------------------------------------+
SQL#2
;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]',c.value('(ReplyItem/ReplyCode/text())[1]',c.value('(ReplyItem/ReplyData/text())[1]',c.value('(ReplyItem/ReplyMsg/text())[1]','VARCHAR(100)')
FROM @XmlDocument.nodes('/SOAP-ENV:Envelope/SOAP-ENV:Body/PlaceOrderResponse/PlaceOrderReplyMessage/ReplyOrder/ReplyGroup') AS t(c);