0

我想構建一個將返回更多或更少複雜XML結構的查詢。這是預期的輸出I想有:使用T-SQL語法生成複雜的XML

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"> 
    <s:Header> 
     <a:Action s:mustUnderstand="1">http://tempuri.org/IGeocodeService/HereRouteMatchExtension</a:Action> 
     <a:MessageID>urn:uuid: some_messageID</a:MessageID> 
     <a:ReplyTo> 
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> 
     </a:ReplyTo> 
     <a:To s:mustUnderstand="1">ServiceURL</a:To> 
    </s:Header> 
    <s:Body> 
       <HereRouteMatchExtension xmlns="http://tempuri.org/"> 
         <vehicleTrace xmlns:b="http://schemas.datacontract.org/2004/07/FMCommonTypes.WCF" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
            <s:Latitude>2</s:Latitude> 
            <s:Longitude>2</s:Longitude> 
            <s:PositionGuid>577AF773-C7A8-4D65-82DA-37A15CC7611D</s:PositionGuid> 
         </vehicleTrace> 
       </HereRouteMatchExtension> 
    </s:Body> 
</s:Envelope> 

我使用以下代碼:

CREATE TABLE #test 
(
    Latitude INT, 
    Longitude INT, 
    PositionGuid UNIQUEIDENTIFIER 
) 

INSERT INTO #test VALUES (1,1,NEWID()) 
INSERT INTO #test VALUES (2,2,NEWID()) 



WITH XMLNAMESPACES ('http://www.w3.org/2003/05/soap-envelope' AS s, 'http://www.w3.org/2005/08/addressing' AS a) 
SELECT 
(SELECT '1' AS [a:Action/@mustUnderstand], 
'http://tempuri.org/IGeocodeService/HereRouteMatchExtension' AS [a:Action] 
    FOR XML PATH (''), TYPE 
), 
'urn:uuid: some_messageID' AS 'a:MessageID', 
(SELECT 'http://www.w3.org/2005/08/addressing/anonymous' AS [a:Address] 
    FOR XML PATH ('a:ReplyTo'), TYPE 
), 
(SELECT '1' AS [a:To/@mustUnderstand], 
'ServiceURL' AS [a:To] 
    FOR XML PATH (''), TYPE 
), 
(SELECT '1' AS [a:Action/@mustUnderstand] 
FOR XML PATH (''), TYPE 

), 
(SELECT Latitude AS 's:Latitude', 
     Longitude  AS 's:Longitude', 
     PositionGuid  AS 's:PositionGuid' 
FROM #test 
FOR XML PATH ('s:Body'), TYPE 
) 

FOR XML RAW ('s:Header'), ELEMENTS, ROOT('s:Envelope') 

有在我生成的代碼2點的問題:

1)參考URL是在每個小節我都只想一次;

2)身體標記是頭內,它應該去後直接就...

我怎樣才能做到這一點?這是我得到的結果:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"> 
    <s:Header> 
    <a:Action xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope" mustUnderstand="1">http://tempuri.org/IGeocodeService/HereRouteMatchExtension</a:Action> 
    <a:MessageID>urn:uuid: some_messageID</a:MessageID> 
    <a:ReplyTo xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"> 
     <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> 
    </a:ReplyTo> 
    <a:To xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope" mustUnderstand="1">ServiceURL</a:To> 
    <a:Action xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope" mustUnderstand="1" /> 
    <s:Body xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"> 
     <s:Latitude>1</s:Latitude> 
     <s:Longitude>1</s:Longitude> 
     <s:PositionGuid>34BD8E91-8567-4D58-A18E-61C3FBBF5C8F</s:PositionGuid> 
    </s:Body> 
    </s:Header> 
</s:Envelope> 
+0

通過「的引用網址」,你的意思是'的xmlns :一個''等命名空間聲明? – IMSoP

+0

是「a」和「s」 –

回答

1

試一下

DECLARE @test TABLE 
(
    Latitude INT, 
    Longitude INT, 
    PositionGuid UNIQUEIDENTIFIER 
) 

INSERT INTO @test VALUES (1,1,NEWID()); 
INSERT INTO @test VALUES (2,2,NEWID()); 

    WITH XMLNAMESPACES ('http://www.w3.org/2003/05/soap-envelope' AS s, 'http://www.w3.org/2005/08/addressing' AS a) 
    SELECT 
     1 AS [s:Envelope/s:Header/a:Action/@s:mustUnderstand], 
     'http://tempuri.org/IGeocodeService/HereRouteMatchExtension' AS [s:Envelope/s:Header/a:Action], 
     'urn:uuid: some_messageID' AS [s:Envelope/s:Header/a:MessageID], 
     'http://www.w3.org/2005/08/addressing/anonymous' [s:Envelope/s:Header/a:ReplyTo/a:Address], 
     1 as [s:Envelope/s:Header/To/@s:mustUnderstand], 
     'ServiceURL' as [s:Envelope/s:Header/To], 
     Latitude as [s:Envelope/s:Body/s:Latitude], 
     Longitude as [s:Envelope/s:Body/s:Longitude], 
     PositionGuid as [s:Envelope/s:Body/s:PositionGuid] 
     FROM @test 
     FOR XML PATH('') 

這樣將產生兩個信封元素一個用於@table的每一行。

編輯:

當鍵入一個子查詢與FOR XML PATH產生我無法找到一個方法來從子元素中刪除多餘的命名空間。

我想出了這個解決方案,它並不能完全滿足我:

DECLARE @test TABLE 
(
    Latitude INT, 
    Longitude INT, 
    PositionGuid UNIQUEIDENTIFIER, 
    x xml 
) 



DECLARE @x xml = 
'<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"> 
    <s:Header> 
     <a:Action s:mustUnderstand="1">http://tempuri.org/IGeocodeService/HereRouteMatchExtension</a:Action> 
     <a:MessageID>urn:uuid: some_messageID</a:MessageID> 
     <a:ReplyTo> 
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> 
     </a:ReplyTo> 
     <a:To s:mustUnderstand="1">ServiceURL</a:To> 
    </s:Header> 
    <s:Body> 
       <HereRouteMatchExtension xmlns="http://tempuri.org/"> 
         <vehicleTrace xmlns:b="http://schemas.datacontract.org/2004/07/FMCommonTypes.WCF" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
            <s:Latitude>2</s:Latitude> 
            <s:Longitude>2</s:Longitude> 
            <s:PositionGuid>577AF773-C7A8-4D65-82DA-37A15CC7611D</s:PositionGuid> 
         </vehicleTrace> 
       </HereRouteMatchExtension> 
    </s:Body> 
</s:Envelope>' 

INSERT INTO @test VALUES (10,10,NEWID(),@x); 
INSERT INTO @test VALUES (20,20,NEWID(),@x); 


UPDATE @test 
SET x.modify('declare namespace s="http://www.w3.org/2003/05/soap-envelope";declare default element namespace "http://tempuri.org/"; 
replace value of (/s:Envelope/s:Body/HereRouteMatchExtension/vehicleTrace/s:Latitude/text())[1] with sql:column("Latitude")') 
UPDATE @test 
SET x.modify('declare namespace s="http://www.w3.org/2003/05/soap-envelope";declare default element namespace "http://tempuri.org/"; 
replace value of (/s:Envelope/s:Body/HereRouteMatchExtension/vehicleTrace/s:Longitude/text())[1] with sql:column("Longitude")') 
UPDATE @test 
SET x.modify('declare namespace s="http://www.w3.org/2003/05/soap-envelope";declare default element namespace "http://tempuri.org/"; 
replace value of (/s:Envelope/s:Body/HereRouteMatchExtension/vehicleTrace/s:PositionGuid/text())[1] with sql:column("PositionGuid")') 


SELECT * FROM @test 

和一次性使用的刀片:

DECLARE @test TABLE 
(
    Latitude INT, 
    Longitude INT, 
    PositionGuid UNIQUEIDENTIFIER, 
    x xml 
) 



DECLARE @x xml = 
'<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"> 
    <s:Header> 
     <a:Action s:mustUnderstand="1">http://tempuri.org/IGeocodeService/HereRouteMatchExtension</a:Action> 
     <a:MessageID>urn:uuid: some_messageID</a:MessageID> 
     <a:ReplyTo> 
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> 
     </a:ReplyTo> 
     <a:To s:mustUnderstand="1">ServiceURL</a:To> 
    </s:Header> 
    <s:Body> 
       <HereRouteMatchExtension xmlns="http://tempuri.org/"> 
       </HereRouteMatchExtension> 
    </s:Body> 
</s:Envelope>' 

INSERT INTO @test VALUES (10,10,NEWID(),@x); 
INSERT INTO @test VALUES (20,20,NEWID(),@x); 

UPDATE @test 
SET x.modify('declare namespace s="http://www.w3.org/2003/05/soap-envelope";declare default element namespace "http://tempuri.org/"; 
insert <vehicleTrace xmlns:b="http://schemas.datacontract.org/2004/07/FMCommonTypes.WCF" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><s:Latitude>{sql:column("Latitude")}</s:Latitude> 
     <s:Longitude>{sql:column("Longitude")}</s:Longitude> 
     <s:PositionGuid>{sql:column("PositionGuid")}</s:PositionGuid></vehicleTrace> into (/s:Envelope/s:Body/HereRouteMatchExtension)[1]') 


SELECT * FROM @test 
+0

謝謝。這正是我所問的。不過,我稍微修改了一下這個問題,你能否看看 ...。我在那裏改了一些代碼。 –

+0

我認爲它也可以用一個插入而不是三個替換 – Blim

+0

謝謝,那麼部分呢?如何生成它? –