Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server XML output with CDATA

Is there a way to have an SQL Server XML return use CDATA? I have XML being returned by SQL Server like this:

<locations>
    <site id="124">
        <sitename>Texas A &amp; M</sitename>
    </site>
</locations>

When I am required to have this:

<locations>
    <site id="124">
        <sitename><![CDATA[Texas A & M]]></sitename>
    </site>
</locations>
like image 412
Steve -Cutter- Blades Avatar asked Sep 15 '09 20:09

Steve -Cutter- Blades


People also ask

How do I add CDATA to XML?

CDATA sections can appear inside element content and allow < and & character literals to appear. A CDATA section begins with the character sequence <! [CDATA[ and ends with the character sequence ]]>. Between the two character sequences, an XML processor ignores all markup characters such as <, >, and &.

Should I use CDATA in XML?

You should almost never need to use CDATA Sections. The CDATA mechanism was designed to let an author quote fragments of text containing markup characters (the open-angle-bracket and the ampersand), for example when documenting XML (this FAQ uses CDATA Sections quite a lot, for obvious reasons).

Is CDATA deprecated?

Note: CDATA is now deprecated. Do not use. The CDATA Section interface is used within XML for including extended portions of text. This text is unescaped text, like < and & symbols.

What does <![ CDATA in XML mean?

The term CDATA, meaning character data, is used for distinct, but related, purposes in the markup languages SGML and XML. The term indicates that a certain portion of the document is general character data, rather than non-character data or character data with a more specific, limited structure.


2 Answers

Look at the options of FOR XML EXPLICIT (parameter Directive). It gives the greater degree of control and you can also specify CDATA. Here is a good tutorial.

And the code addapted from that tutorial:

declare @agent table
(    
    AgentID int,
    Fname varchar(5),
    SSN varchar(11)
)

insert into @agent
select 1, 'Vimal', '123-23-4521' union all
select 2, 'Jacob', '321-52-4562' union all
select 3, 'Tom', '252-52-4563'

SELECT
    1 AS Tag,
    NULL AS Parent,
    NULL AS 'Agents!1!',
    NULL AS 'Agent!2!AgentID',
    NULL AS 'Agent!2!Fname!Element',
    NULL AS 'Agent!2!SSN!cdata'
UNION ALL
SELECT
    2 AS Tag,
    1 AS Parent,
    NULL, 
    AgentID,
    Fname,
    SSN
FROM @agent
FOR XML EXPLICIT
like image 165
Lukasz Lysik Avatar answered Nov 13 '22 08:11

Lukasz Lysik


Here is an example of my way of getting CDATA:

DECLARE @GlobalDateFormat varchar(32)
SET @GlobalDateFormat = 'MM/dd/yyyy hh:mm tt'

DECLARE @xml XML

SET @xml = 
(
    SELECT
            SegmentId         = ISNULL(SegmentId,0)
        ,   DocumentId        = ISNULL(DocumentId,0)
        ,   Title             = CAST(Core.dbo.fCharFormat('xmlCDATA',Title,DEFAULT,'') AS xml)
        ,   DocumentShortName = CAST(Core.dbo.fCharFormat('xmlCDATA',DocumentShortName,DEFAULT,'') AS xml)
        ,   [FileName]        = CAST(Core.dbo.fCharFormat('xmlCDATA',[FileName],DEFAULT,'') AS xml)
        ,   [Path]            = CAST(Core.dbo.fCharFormat('xmlCDATA',[Path],DEFAULT,'') AS xml)
        ,   CreateDate        = ISNULL(Core.dbo.fDateFormat(@GlobalDateFormat,CreateDate),Core.dbo.fDateFormat(@GlobalDateFormat,GETDATE()))
        ,   ModificationDate  = ISNULL(Core.dbo.fDateFormat(@GlobalDateFormat,ModificationDate),Core.dbo.fDateFormat(@GlobalDateFormat,GETDATE()))
        ,   TemplateId        = ISNULL(CAST(TemplateId AS varchar(16)),'')
        ,   IsRoot            = ISNULL(IsRoot,0)
        ,   IsActive          = ISNULL(IsActive,0)
        ,   SortOrdinal       = ISNULL(CAST(SortOrdinal AS varchar(16)),'')
        ,   ClientId          = ISNULL(ClientId,'')
        ,   Tag               = CAST(Core.dbo.fCharFormat('xmlCDATA',Tag,DEFAULT,'') AS xml)
        FROM
            Document
        WHERE
            DocumentId = 9073
        FOR XML AUTO, ELEMENTS
)

SELECT @xml

Here is the relevant detail from my weasel-like, CDATA-handling function:

IF @cmdName = 'xmlCDATA'
BEGIN
    IF @chars IS NULL
    BEGIN
        SET @charsOut = @charsDefault
    END
    ELSE
    BEGIN
        SET @chars = REPLACE(@chars,'<![CDATA[','')
        SET @chars = REPLACE(@chars,']]>','')
        SET @charsOut = '<![CDATA[' + @chars + ']]>'
    END
END
like image 43
rasx Avatar answered Nov 13 '22 09:11

rasx