sql - 在 Oracle SQL 中更新 XML 时如何不转义特殊字符

标签 sql xml oracle

我在尝试更新 oracle 中的 xmlType 值时遇到问题。 我需要修改类似于以下内容的 xml:

<a>
  <b>Something to change here</b>
  <c>Here is some narrative containing weirdly escaped &lt;tags>\&lt;/tags> </c>
</a>

我想实现的是修改而不修改

不幸的是以下modifyXml:

select 
  updatexml(XML_TO_MODIFY, '/a/b/text()', 'NewValue')
from dual;

返回这个:

<a>
  <b>NewValue</b>
  <c>Here is some narrative containing weirdly escaped &lt;tags&gt;&lt;/tags&gt; </c>
</a>

如您所见,“>”已被转义。

xmlQuery(updateXml 的新的非弃用版本)也是如此:

select /*+ no_xml_query_rewrite */
      xmlquery(
        'copy $d := .
         modify (
           for $i in $d/a
           return replace value of node $i/b with ''nana''
         )
         return $d'
        passing t.xml_data
         returning content
       ) as updated_doc
from (select xmlType('<a>
      <b>Something to change here</b>
      <c>Here is some narrative containing weirdly escaped \&lt;tags>\&lt;/tags> </c>
    </a>') as xml_data from dual) t
;

同样,当使用 xmlTransform 时,我会得到相同的结果。 我尝试使用

disable-output-escaping="yes"

但它的作用恰恰相反——它没有转义 < :

select XMLTransform(
    xmlType('<a>
      <b>Something to change here</b>
      <c>Here is some narrative containing weirdly escaped \&lt;tags>\&lt;/tags> </c>
    </a>'),
    XMLType(
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/a/b">
                <b>
                <xsl:value-of select="text()"/>
                </b>
        </xsl:template>

        <xsl:template match="/a/c">
                <c>
                <xsl:value-of select="text()" disable-output-escaping="yes"/>
                </c>
        </xsl:template>
</xsl:stylesheet>'))
from dual;

返回:

<a>
  <b>NewValue</b>
  <c>Here is some narrative containing weirdly escaped <tags></tags> </c>
</a>

有什么建议吗? 您需要知道的两件事:

  1. 我无法修改初始格式 - 它以这种方式出现并且 我需要保存它。
  2. 原来的消息太大了,改变 字符串和返回的消息(使用正则表达式作为解决方法)将 别耍花招。

最佳答案

问题的根源似乎是节点 C 的原始 XML 值如果包含 > 则不是有效的 XML。在值内而不是 &gt; , 而不是在 CDATA section 内(还有 What does <![CDATA[]]> in XML mean? )。

字符串值:

Here is some narrative containing weirdly escaped &lt;tags>\&lt;/tags>

XML 格式确实应该是

<c>Here is some narrative containing weirdly escaped &amp;lt;tags&gt;\&amp;lt;/tags&gt;</c>

<c><![CDATA[Here is some narrative containing weirdly escaped &lt;tags>\&lt;/tags>]]></c>

我会要求在源头更正 XML,或者自己实现一些方法来清理输入,例如包装 <c> <![CDATA[]]> 中的节点值.如果您需要保存准确的原始值,并且消息很大,那么我能想到的最好的方法是存储重复副本,原始值为字符串,并将“清理”值存储为 XML 数据类型。

关于sql - 在 Oracle SQL 中更新 XML 时如何不转义特殊字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27485835/

相关文章:

c++ - Oracle 中触发 SQL 查询的底层机制

Oracle SELECT 查询 : collapsing null values when pairing up dates

sql - 获取 SQL 服务器组中可用服务器的列表

java - 在Java中设置editText的长度限制

python - 如何修复 PyXML?

xml - 在 XML 中编写 HTTP header

sql - 了解基本的 SQL 查询

php - 简单的 MySQL 调用在特定键处选择整数不起作用?

sql - 根据两个多对多关系选择行

sql - 子查询返回多个值