操纵XMLNamespaces

时间:2017-10-16 13:25:14

标签: sql-server xml xpath namespaces

我使用FOR XML子句从SQL获得以下输出:

<q17:DestinationSection xmlns:q17="http://ITrack.Transmission/2011/02/25/Objects">
<q17:DestinationCode>1</q17:DestinationCode>
<q17:DestinationName>Strada Rampei 9, Iasi</q17:DestinationName>
<q17:DestinationAddress1>Strada Rampei 9, Iasi</q17:DestinationAddress1>
<q17:DestinationAddress2>
xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
</q17:DestinationAddress2>
</q17:DestinationSection>

DestinationSection是此数据块的主根。有没有可能做一些解决方法,并在<q17:DestinationAddress2></q17:DestinationAddress2>标签中有类似下面的内容?

<q17:DestinationAddress2 xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</q17:DestinationAddress2>

我尝试了一些东西,但是我收到一条错误消息,说我需要声明命名空间但我真的不知道在哪里&#34;介绍&#34;那个定义。

我的SQL语句

DECLARE @XMLFINAL VARCHAR(MAX)
SET @XMLFINAL=''
DECLARE @XMLFINAL2 VARCHAR(MAX)
SET @XMLFINAL2=''
DECLARE @NUMBER NVARCHAR(100)
DECLARE @NUMBER2 NVARCHAR(100)
DECLARE @XML VARCHAR(MAX)
DECLARE @XML2 VARCHAR(MAX)

DECLARE Rec CURSOR FAST_FORWARD FOR

SELECT  GID FROM PurchaseDocumentsHeader

OPEN Rec
FETCH NEXT FROM Rec INTO @NUMBER2
WHILE @@FETCH_STATUS = 0 
BEGIN
SET @XML2=''    


;WITH XMLNAMESPACES ('http://ITrack.Transmission/2011/02/25/Objects' as q17)


SELECT @XML2= (

SELECT 
DestCode AS 'q17:DestinationCode', DestDescr 'q17:DestinationName', DestAddr AS 'q17:DestinationAddress1', DestAddr2 AS 'q17:DestinationAddress2',
DestZIP AS 'q17:DestinationZIP'

FROM PurchaseDocumentsHeader WHERE GID=@NUMBER2
FOR XML RAW('q17:DestinationSection'),ELEMENTS
)

FETCH NEXT FROM Rec INTO @NUMBER2

SET @XMLFINAL2=@XMLFINAL2+@XML2
END

CLOSE Rec DEALLOCATE Rec

修改

请在下面找到我的DDL。它是用于从官方表格中提取数据的视图。

CREATE VIEW [dbo].[PurchaseDocumentsHeader]
AS
SELECT esd.GID, esd.ADRegistrationDate, esgo.Code AS DestCode, esgo.Description AS DestDescr, esgo.Address1 AS DestAddr, esgo.fCityCode AS DestCity,
 esgp.TaxRegistrationNumber AS DestZIP, 'xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' AS DestAddr2, esgo.Description AS DestRomanized,
 esgo.Address1 AS DestAddress1Romanized, 
 'xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' AS DestAddress2Romanized,  esgp.TaxRegistrationNumber AS DestZIPRom,  
 esgo.fCityCode AS DestCityRomanized, esgo.fCountryCode AS DestCountry, cast('DestinationGLN xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>' AS XML) AS DestGLN, 
 'xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' AS DestCoord
FROM ESFIDocumentTrade esd
LEFT JOIN ESGOSites esgo on esd.fDeliverySiteGID=esgo.GID
LEFT JOIN ESFITradeAccount esc on esd.fTradeAccountGID=esc.GID
LEFT JOIN ESGOPerson esgp on esc.fPersonCodeGID=esgo.GID
LEFT JOIN ESFIDocumentType est on esd.fADDocumentTypeGID=est.GID
WHERE esd.fTransitionStepCode='APPROVED' AND est.Code='CVR'
AND YEAR(esd.ADRegistrationDate)=YEAR(GETDATE())
AND MONTH(esd.ADRegistrationDate)=MONTH(GETDATE())
AND DAY(esd.ADRegistrationDate)=DAY(GETDATE())

GO

稍后修改

CREATE TABLE DocPurcharseHeader
(
ADRegistrationDate date,
Code NVARCHAR(4000),
Description NVARCHAR(4000),
Address1 NVARCHAR (4000),
Address2 NVARCHAR (4000),
City NVARCHAR (4000),
ZIPCode NVARCHAR(4000)
)

INSERT INTO DocPurcharseHeader (ADRegistrationDate, Code, Description, Address1, Address2, City, ZIPCode)
VALUES('2017-10-16', '01', 'MyPOS', 'MyPOSAddress1', 'MyPOSAddress2', 'BUCHAREST', '123456')

第二次编辑

;WITH XMLNAMESPACES ('http://ITrack.Transmission/2011/02/25/Objects' as q17)

    SELECT @XMLSalesOrders=(
    SELECT DestCode AS [q17:DestinationCode]
          ,DestDescr AS [q17:DestinationName]
          ,DestAddr AS [q17:DestinationAddress1]
          ,DestAddr2 AS [q17:DestinationAddress2]
    FROM PurchaseDocumentsHeader
    FOR XML PATH('q17:DestinationSection'),ELEMENTS XSINIL,ROOT('q17:DestinationSections'))

上面的代码生成以下输出,没有XSINL指令:

<q17:DestinationSections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:q17="http://ITrack.Transmission/2011/02/25/Objects">
<q17:DestinationSection>
<q17:DestinationCode>1</q17:DestinationCode>
<q17:DestinationName>Strada Rampei 9, Iasi</q17:DestinationName>
<q17:DestinationAddress1>Strada Rampei 9, Iasi</q17:DestinationAddress1>
<q17:DestinationAddress2/>
</q17:DestinationSection>
<q17:DestinationSection>

1 个答案:

答案 0 :(得分:1)

你正试图超越强大的XML引擎。

如您的其他问题所述:

永远不要在CURSOR中做到这一点!他们是坏的和邪恶的,直接来自程序性思维的地狱,是由意大利面条代码的魔鬼发明的......

试试这样:

我使用你的表DDL插入一些数据。第二行在地址2中将有NULL。通常,XML将简单地省略NULL值。不存在的节点将被读取为NULL值。但您可以NULL强制xsi.nil="true"作为ELEMENTS XSINIL加入{<1}}:

CREATE TABLE DocPurcharseHeader
(
ADRegistrationDate date,
Code NVARCHAR(4000),
Description NVARCHAR(4000),
Address1 NVARCHAR (4000),
Address2 NVARCHAR (4000),
City NVARCHAR (4000),
ZIPCode NVARCHAR(4000)  
);

INSERT INTO DocPurcharseHeader (ADRegistrationDate, Code, Description, Address1, Address2, City, ZIPCode)
VALUES('2017-10-16', '01', 'MyPOS', 'MyPOSAddress1', 'MyPOSAddress2', 'BUCHAREST', '123456')
     ,('2017-10-16', '01', 'MyPOS', 'MyPOSAddress1', NULL, 'BUCHAREST', '123456');

WITH XMLNAMESPACES('http://ITrack.Transmission/2011/02/25/Objects' AS q17)
SELECT Code AS [q17:DestinationCode]
      ,Description AS [q17:DestinationName]
      ,Address1 AS [q17:DestinationAddress1]
      ,Address2 AS [q17:DestinationAddress2]
FROM DocPurcharseHeader
FOR XML PATH('q17:DestinationSection'),ELEMENTS XSINIL,ROOT('q17:DestinationSections');

结果

<q17:DestinationSections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:q17="http://ITrack.Transmission/2011/02/25/Objects">
  <q17:DestinationSection>
    <q17:DestinationCode>01</q17:DestinationCode>
    <q17:DestinationName>MyPOS</q17:DestinationName>
    <q17:DestinationAddress1>MyPOSAddress1</q17:DestinationAddress1>
    <q17:DestinationAddress2>MyPOSAddress2</q17:DestinationAddress2>
  </q17:DestinationSection>
  <q17:DestinationSection>
    <q17:DestinationCode>01</q17:DestinationCode>
    <q17:DestinationName>MyPOS</q17:DestinationName>
    <q17:DestinationAddress1>MyPOSAddress1</q17:DestinationAddress1>
    <q17:DestinationAddress2 xsi:nil="true" />
  </q17:DestinationSection>
</q17:DestinationSections>

更新:关于NULL值:

试试这个

DECLARE @DummyTable TABLE(SomeDescription VARCHAR(500), SomeValue VARCHAR(100));
INSERT INTO @DummyTable VALUES('A real NULL value',NULL)
                             ,('An empty string','')
                             ,('A blank string','   ')
                             ,('Some Text','blah blah');

WITH XMLNAMESPACES('SomeURL' AS q17)
SELECT SomeDescription AS [q17:Description]
      ,SomeValue AS [q17:Value]
FROM @DummyTable                
FOR XML PATH('q17:row'),ELEMENTS XSINIL,ROOT('root');   

要得到这个

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:q17="SomeURL">
  <q17:row>
    <q17:Description>A real NULL value</q17:Description>
    <q17:Value xsi:nil="true" />
  </q17:row>
  <q17:row>
    <q17:Description>An empty string</q17:Description>
    <q17:Value></q17:Value>
  </q17:row>
  <q17:row>
    <q17:Description>A blank string</q17:Description>
    <q17:Value>   </q17:Value>
  </q17:row>
  <q17:row>
    <q17:Description>Some Text</q17:Description>
    <q17:Value>blah blah</q17:Value>
  </q17:row>
</root>

您可以看到, real NULL 编码为xsi:nil="true",而空字符串显示为<q17:Value></q17:Value>(与{{1}完全相同})。

查看this answer,了解有关<q17:Value />NULL的一些示例。查看this answer以了解有关empty

的更多信息