XML 解析和发出行为变更(待定)

注意

此行为变更在 2025_01 捆绑包中。

有关捆绑包的当前状态,请参阅 捆绑包历史记录

启用此行为变更捆绑包后,使用 XML 文件格式的 COPY INTO <table> 命令以及调用以下函数时,解析和发出 XML 内容将发生更改:

变更前:

XML 解析和发出行为:

  • 某些调用 CHECK_XML 函数的查询返回带错误消息的字符串。

  • 某些调用 PARSE_XML 函数的查询失败。

变更后:

XML 解析和发出行为:

  • 某些查询在更改前调用 CHECK_XML 函数时返回带错误消息的字符串,而现在返回 NULL。

  • 某些查询在更改前调用 PARSE_XML 函数时失败,而现在会成功,并且函数返回解析的 XML。

  • 具有包含尖括号或撇号的 XML 字符串的查询,在更改后返回不同的结果。

  • 具有包含空格的 XML 字符串或与保留空格相关的 XML 属性的查询,在更改后返回不同的结果。

以下部分提供有关更改的更多详细信息。

解析包含处理指令的 XML 内容

以下示例使用 PARSE_XML 函数解析处理指令中带问号的 XML 内容:

SELECT PARSE_XML('<?PITarget PIContent ??><mytag />') AS mytag;
Copy
更改前返回::
100100 (22P02): Error parsing XML: prematurely terminated XML document in processing instructions, pos 33
更改后返回::
+-----------------+
| MYTAG           |
|-----------------|
| <mytag></mytag> |
+-----------------+

解析包含尖括号或撇号的 XML 内容

以下示例使用 PARSE_XML 函数解析在 XML 属性值中包含尖括号和撇号的 XML 内容。更改后,XML 属性值中的撇号和尖括号在返回值和发出的 XML 中会正确转义:

SELECT PARSE_XML('<mytag myattr="&lt;&gt;\'"/>') AS mytag;
Copy
更改前返回::
+------------------------------+
| MYTAG                        |
|------------------------------|
| <mytag myattr="<>'"></mytag> |
+------------------------------+
更改后返回::
+-----------------------------------------+
| MYTAG                                   |
|-----------------------------------------|
| <mytag myattr="&lt;&gt;&apos;"></mytag> |
+-----------------------------------------+

解析包含用户定义实体的 XML 内容

以下示例使用 PARSE_XML 函数解析包含用户定义实体的 XML 内容:

SELECT PARSE_XML('<!DOCTYPE doc [<!ENTITY placeholder "some text">]><doc>&placeholder;</doc>')
  AS placeholder;
Copy
更改前返回::
100100 (22P02): Error parsing XML: unknown entity &placeholder;, pos 68
更改后返回::
+-------------------------------------------------------------+
| PLACEHOLDER                                                 |
|-------------------------------------------------------------|
| <!DOCTYPE doc [<!ENTITY placeholder "some                   |
| text">]><doc>some text</doc>                                |
+-------------------------------------------------------------+

解析保留空格的 XML 内容

之所以进行此变更,是为了 Snowflake 中的行为符合有关空格保留的 XML 规范 (https://www.w3.org/TR/xml11/#sec-white-space):

  • 变更前,xsl:space="preserve" 属性会保留空格。变更后,xsl:space="preserve" 属性不会保留空格。

  • 变更前,xml:space="preserve" 属性不会保留空格。变更后,xml:space="preserve" 属性会保留空格。

以下示例使用 PARSE_XML 函数解析 XML 内容并指定 xsl:space="preserve" 属性:

SELECT PARSE_XML('<mytag xsl:space="preserve"> my content </mytag>')
  AS space_preserve;
Copy
更改前返回::
+--------------------------------------------------+
| SPACE_PRESERVE                                   |
|--------------------------------------------------|
| <mytag xsl:space="preserve"> my content </mytag> |
+--------------------------------------------------+
更改后返回::
+--------------------------------------------------+
| SPACE_PRESERVE                                   |
|--------------------------------------------------|
| <mytag xsl:space="preserve">my content</mytag>   |
+--------------------------------------------------+

以下示例使用 PARSE_XML 函数解析 XML 内容并指定 xml:space="preserve" 属性:

SELECT PARSE_XML('<mytag xml:space="preserve"> my content </mytag>')
  AS space_preserve;
Copy
更改前返回::
+--------------------------------------------------+
| SPACE_PRESERVE                                   |
|--------------------------------------------------|
| <mytag xml:space="preserve">my content</mytag>   |
+--------------------------------------------------+
更改后返回::
+--------------------------------------------------+
| SPACE_PRESERVE                                   |
|--------------------------------------------------|
| <mytag xml:space="preserve"> my content </mytag> |
+--------------------------------------------------+

加载保留空格的 XML 内容

以下示例使用 COPY INTO <table> 命令将数据加载到表中。PRESERVE_SPACE 参数设置为 TRUE 以保留空格:

COPY INTO mytable
  FROM @my_xml_stage
  FILE_FORMAT = (TYPE = 'XML' PRESERVE_SPACE = TRUE);
Copy
变更前加载的内容::
+--------------------------------------------------+
| SPACE_PRESERVE                                   |
|--------------------------------------------------|
| <mytag xsl:space="preserve"> my content </mytag> |
+--------------------------------------------------+
变更后加载的内容::
+--------------------------------------------------+
| SPACE_PRESERVE                                   |
|--------------------------------------------------|
| <mytag xml:space="preserve"> my content </mytag> |
+--------------------------------------------------+

在变更前后,内容会保留空格,但属性会从 xsl:space="preserve" 变为 xml:space="preserve"

参考:1862

语言: 中文