При использовании bcp queryout в итоговом xml файл происходит неожиданный \n

Нужно выгружать из SSMS файл в формате XML. Делаю это следующим способом:

DECLARE @cmd  VARCHAR(2000);
DECLARE @path  VARCHAR(300)
DECLARE @servname  VARCHAR(50)
DECLARE @query  VARCHAR(1000)

SET @servname = 'Sever'
SET @query = '"SELECT * FROM [DB].[dbo].[Table] FOR XML PATH(''AB''), ROOT(''ALL_AB'')"'
SET @path = 'C:\XML_test\xml1.xml'
SET @cmd = 'bcp.exe ' + @query + ' queryout ' + @path + ' -c -C 65001 -U usname -P psw  -S ' + @servname;
EXEC xp_cmdshell  @cmd ;

Файл формируется, все хорошо, однако есть одно НО: в формирующемся XML файле в одном из полей неожиданно возникает \n. А стирать этот переход на след строку каждый раз не вариант.

Должно быть "<ПолеАБВ>0</ПолеАБВ>", а делает "<ПолеАБВ>0</Поле

АБВ>". Подскажите, как избавиться от данной проблемы?

Причем это происходит только в 1-ом элементе. В последующих такого перехода на новую строку не происходит


Ответы (1 шт):

Автор решения: Yitzhak Khabinsky

bcp ничего не знает об XML. bcp сохраняет данные в формате XML как потоковые данные (stream) в файл. Этот XML-файл не имеет индентации (indentation) по определению. Вам потребуется добавить дополнительный шаг в общий процесс, чтобы сделать индентацию (indentation) для XML-файла.

XSLT — лучшая технология для этого. XSLT всегда доступен на компьютере с ОС Windows.

xslt-процессор встроен в .Net Framework.

В XSLT есть так называемый Identity Transform шаблон для таких задач.

XSLT

IndentGeneric.xslt файл

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output  method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="no"/>

   <xsl:strip-space elements="*"/>

   <!--Identity transform-->
   <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

Для выполнения преобразования XSLT мы можем использовать простой трехстрочный скрипт Powershell.

Powershell

XSLT-Transformation.ps1 файл

$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
$xslt.load("C:\XML_test\IndentGeneric.xslt")
$xslt.Transform("C:\XML_test\Input.xml", "C:\XML_test\Output.xml")

Откройте командную строку Powershell и выполните .\XSLT-Transformation.ps1

→ Ссылка