在单个查询中将VARCHAR(max)列转换为大写然后转换为XML

时间:2018-12-08 01:18:42

标签: sql-server tsql

我尝试在StackOverflow中搜索失败。

我想在VARCHAR(max)列上执行以下两次转换,但是在一个查询中。这是T-SQL。

  1. 使用UPPER()函数将列中的所有文本转换为大写
  2. 使用XML函数将列转换为CAST(column AS XML)数据类型

我在下面尝试过,语法上不正确。

SELECT CAST(UPPER(inputText) AS XML) AS ConvertedText 
FROM SampleTable

SSMS返回错误。 (当我删除UPPER()时,查询运行没有错误。)

  

以“ xml”开头的命名空间被保留

1 个答案:

答案 0 :(得分:1)

XML严格区分大小写。用字符串方法处理XML总是很危险的。因为XML不仅是带有一些花哨的字符的字符串 ...

您的XML是-我从发布的错误消息中获取的-包括 xml声明。另外,我将谈论名称空间。 XML期望使用小写 xml-declaration 和命名空间声明。这不能大写。

检查一下:我定义了一个XML,带有一个声明,一个默认名称空间和一个带前缀的名称空间。

DECLARE @testXML NVARCHAR(MAX)=
N'<?xml version="1.0" encoding="UTF-16"?>
  <root xmlns="dummy.default" xmlns:blah="Some.blah.namespace">
    <test a="attribute value">element value</test>
    <blah:NamespacedElement>value in a namespaced element</blah:NamespacedElement>
  </root>';

SELECT UPPER(@testXML);
/*
  <?XML VERSION="1" ENCODING="UTF-16"?>
  <ROOT XMLNS="DUMMY.DEFAULT" XMLNS:BLAH="SOME.BLAH.NAMESPACE">
    <TEST A="ATTRIBUTE VALUE">ELEMENT VALUE</TEST>
    <BLAH:NAMESPACEDELEMENT>VALUE IN A NAMESPACED ELEMENT</BLAH:NAMESPACEDELEMENT>
  </ROOT>
*/

-声明已损坏,因为所有内部内容均应为小写。但这很容易。我们可以将其完全切掉。在SQL Server中,此声明没有意义。在任何情况下都将被忽略...
-其次,我们必须处理xmlns

SELECT SUBSTRING(REPLACE(UPPER(@testXML),'xmlns','xmlns'),PATINDEX('%?>%',@testXML)+2,1000000);
/*
  <ROOT xmlns="DUMMY.DEFAULT" xmlns:BLAH="SOME.BLAH.NAMESPACE">
    <TEST A="ATTRIBUTE VALUE">ELEMENT VALUE</TEST>
    <BLAH:NAMESPACEDELEMENT>VALUE IN A NAMESPACED ELEMENT</BLAH:NAMESPACEDELEMENT>
  </ROOT>
*/

-您可以看到声明已消失,xmlns现在是小写字母。可以将其转换为XML:

SELECT CAST(SUBSTRING(REPLACE(UPPER(@testXML),'xmlns','xmlns'),PATINDEX('%?>%',@testXML)+2,1000000) AS XML)

但是-坦白说-如果这不仅仅是一件奇怪的家庭作业,则永远不要更改整体的XML大小写(包括标记)。