How to use FOR XML PATH('') in a query without escaping special characters? How to use FOR XML PATH('') in a query without escaping special characters? sql sql

How to use FOR XML PATH('') in a query without escaping special characters?


Use ,TYPE).value('.','NVARCHAR(MAX)') and your special characters will not be escaped:

SELECT DISTINCT            f.CourseEventKey,            (                SELECT      f.Title + '; ' AS [text()]                FROM        @Facilities                WHERE       CourseEventKey = f.CourseEventKey                ORDER BY    f.Title                FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)')            AS FacilitiesFROM        @Facilities f

Credit for this goes to Rob Farley.

UPDATE:
I just heard about this new method. I haven't tested it thoroughly yet, and would appreciate any feedback. We can replace [text()] with [processing-instruction(x)], like this

select 'hello & there >' as [processing-instruction(x)] FOR XML PATH('')

will return

<?x hello & there >?>

We just need to strip off the <? ... ?>


I think you're going to have to manually wrap the Facilities inline query block with REPLACE statements to reverse the automatic escaping.

It sounds like what you're wanting to do is concatenate multiple facilities that could present a given course. Have you considered other options? This question has several possible approaches that don't have an issue with escaping your characters.


Adding to the latest solution provided by @Baodad, simply REPLACE the <? ... ?>.

SELECT DISTINCT        f.CourseEventKey,        REPLACE(        REPLACE(                (                SELECT f.Title + '; ' AS [processing-instruction(x)]                FROM Facilities                WHERE CourseEventKey = f.CourseEventKey                ORDER BY f.Title                FOR XML PATH('')                )                , '<?x','')                , '?>','') FacilitiesFROM Facilities f`

Your output will be:

| CourseEventKey |                                 Facilities ||----------------|--------------------------------------------||             29 |        Test Facility 1;  Test Facility 1;  ||             29 |      Test Facility 33;  Test Facility 33;  ||             30 |                    Memphis Training Room;  ||             31 |                            Another place;  ||             32 |  Drury Inn & Suites;  Drury Inn & Suites;  ||             32 |    Yet Another place;  Yet Another place;  |

This works because your final output is not in XML, otherwise REPLACE would simply not work as the characters would remain encoded.