使用OPENXML从XML中删除回车符号

时间:2011-11-26 20:58:39

标签: sql sql-server xml parsing openxml

在解析XML时,SQL Server似乎删除了\r个字符。因此,当我的存储过程收到xml中的值以进行保存时,所有换行符都表示为\n而不是\r\n.

有什么办法可以强制SQL Server不删除\r个字符?在下面的示例中,Node1值不包含\r个符号。


    DECLARE @hDoc int
    DECLARE @Xml nvarchar(MAX) 
    SET @Xml = N'<Root><Node1><![CDATA[' + nchar(13) + nchar(10) + N'Some ' + nchar(13) + nchar(10) + N' Value]]></Node1></Root>'
    EXEC sp_xml_preparedocument @hDoc OUTPUT, @Xml

    SELECT 
        Node1
        ,convert(varbinary(max),Node1) -- Contains 0A00 in the start instead of 0D0A,
        ,charindex(nchar(13),Node1)
    FROM
        OPENXML(@hDoc, N'/Root', 2) WITH (Node1 NVARCHAR(MAX))

    EXEC sp_xml_removedocument @hDoc

输出:
 enter image description here

@PJB建议改为使用XQuery nodes。但这没有帮助。我尝试在下面运行查询并获得相同的结果。


    DECLARE @xml xml
    SET @xml = convert(xml, N'<Root><Node1><![CDATA[' + nchar(13) + nchar(10) + N'Some ' + nchar(13) + nchar(10) + N' Value]]></Node1></Root>')

    declare @Node1 nvarchar(30)
    select @Node1 = node.value('.', 'nvarchar(30)')
    from @xml.nodes('/Root/Node1') as doc(node)

    SELECT 
        @Node1
        ,convert(varbinary(max),@Node1) -- Contains 0A00 in the start instead of 0D0A,
        ,charindex(nchar(13),@Node1)

2 个答案:

答案 0 :(得分:3)

  

从XML中删除回车符号

根据End-of-Line Handling上的XML规范,这是正确的行为。

  

XML处理器必须表现得好像它标准化了所有换行符   输入时外部解析的实体(包括文档实体),   在解析之前,通过翻译两个字符的序列#xD #xA   以及任何#xD后面没有#xA到单个#xA字符。

您可以尝试使用replace来返回回车。

select @Node1 = replace(node.value('.', 'nvarchar(30)'), nchar(10), nchar(13)+nchar(10))
from @xml.nodes('/Root/Node1') as doc(node)

答案 1 :(得分:0)

也许最好在业务甚至客户层中解决它,以免更改数据库中应用的标准。 例如,如果您在NET Framework中有一个应用程序,则可能是这样,在检索值时,可以应用适当的替换:

对于Windows.Forms:替换单独的LF。

var result = Regex.Replace("Line 1\r\nLine2\nLine3\nLine4",  @"(?<!\r)\n(?!\r)", Environment.NewLine);

对于HTML:用首选的换行符替换您考虑的组合。

var result = "Line 1\r\nLine2\nLine3\nLine4".Replace("\r\n", "<br />").Replace("\n", "<br />");

环顾四周模式的想法来自:

Replace only one char not preceded or followed by X