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

问题描述 投票:0回答:1

我尝试在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”开头的名称空间是保留的

sql-server tsql
1个回答
1
投票

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

您的XML是 - 我从发布的错误消息中获取此信息 - 包括xml声明。此外,我将谈论名称空间。 XML期望以小写形式表示命名空间的xml声明和声明。这不能是大写的。

看看这个:我定义了一个带有声明,默认命名空间和一个前缀命名空间的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的大小。

© www.soinside.com 2019 - 2024. All rights reserved.