首页 > 解决方案 > 在单个查询中将 VARCHAR(max) 列转换为大写,然后再转换为 XML

问题描述

我尝试在 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-servertsql

解决方案


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

您的 XML 是 - 我从发布的错误消息中获取 - 包括xml-declaration。另外,我将讨论命名空间。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 的大小写。


推荐阅读