Oracle XML 解析失败,在 Name 或 Nmtoken 中发现无效字符

Posted

技术标签:

【中文标题】Oracle XML 解析失败,在 Name 或 Nmtoken 中发现无效字符【英文标题】:Oracle XML parsing failed , invalid character found in a Name or Nmtoken 【发布时间】:2013-10-30 03:54:43 【问题描述】:

以下代码适用于非整数。 我有几个带有整数的标签(比如<1><2> 等),

SET serveroutput ON
alter session set cursor_sharing = exact;
with xmldata(d) as (select xmltype('<ROWSET><ROW><1>ABC</1></ROW></ROWSET>') from dual
)
select x.*
FROM xmldata,
     xmltable('ROWSET/ROW' passing xmldata.d
              columns
              name varchar2(10) path '1'
     ) x
;

我也试过用这个:

DECLARE
l_xml xmltype;
l_val VARCHAR2(1000) := '<ROWSET><ROW><1>ABC</1></ROW></ROWSET>';
BEGIN
     l_xml        := xmltype(l_val);
end;

两者都会导致以下错误:

Error report:
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00231: invalid character 49 ('1') found in a Name or Nmtoken
Error at line 1
ORA-06512: at "SYS.XMLTYPE", line 310
ORA-06512: at line 5
31011. 00000 -  "XML parsing failed"
*Cause:    XML parser returned an error while trying to parse the document.
*Action:   Check if the document to be parsed is valid.

提前感谢和赞赏:)

【问题讨论】:

您运行的是哪个 Oracle 版本? Eeek....这是 11gR2 的基本版本。我强烈建议尽快升级到 11.2.0.4.0。 【参考方案1】:

错误:

LPX-00231: invalid character 49 ('1') found in a Name or Nmtoken

是因为在您的 XML 中有一个元素 1:

<1>ABC</1>

其中&lt;1&gt; 是start tag(而&lt;/1&gt; 是end tag)。在标签中1 是the name,它给出了元素的类型。名字有一定的naming rules:

[定义:名称是一个以字母或几个标点字符之一开头的记号,后面是字母、数字、连字符、下划线、冒号或句号,统称为名称字符。] 以字符串 "xml" 或任何匹配的字符串 (('X'|'x') ('M'|'m') ('L'|'l')) 保留用于在此或本规范的未来版本。

Name 的第一个字符必须是 NameStartChar,其他任何字符都必须是 NameChars;此机制用于防止名称以欧洲 (ASCII) 数字或基本组合字符开头。几乎所有字符都可以在名称中使用,除了那些可以用作或可以合理用作分隔符的字符。

NameNameStartChar 的确切定义是here。

像往常一样,从W3School 找到更人性化的解释:

XML 元素必须遵循以下命名规则:

名称可以包含字母、数字和其他字符

名称不能以数字或标点符号开头

名称不能以字母 xml(或 XML,或 Xml 等)开头

名称不能包含空格

可以使用任何名称,不保留任何单词。

总结:

始终以字母开头元素名称 - 使用 COL1 而不是 1COL

【讨论】:

【参考方案2】:

实际上,我不需要知道 Oracle 版本(但一般来说,最好在提问时始终提供它)。

错误 LPX-00231 似乎是不言自明的。您不能以数字开头的名称。如果您将代码更改为:

SET serveroutput ON
alter session set cursor_sharing = exact;
with xmldata(d) as (select xmltype('<ROWSET><ROW><A1>ABC</A1></ROW></ROWSET>') from dual
)
select x.*
FROM xmldata,
     xmltable('ROWSET/ROW' passing xmldata.d
              columns
              name varchar2(10) path '1'
     ) x
;

然后它就可以正常工作了。

希望对您有所帮助....

【讨论】:

希望你的意思是path 'A1'`,我知道它有效。那么,我的查询在 (11.2.0.4.0) 及以上的查询中是否能正常工作?这只是我当前版本 (11.2.0.1.0) 的问题吗? 不,你误会了。 Oracle 版本无关紧要,因为错误在您的代码中,而不是 Oracle。您不能有一个以数字 (0-9) 开头的标签(不确定这是否是正确的术语)。因此,ABC1> 无效。当我将其更改为 ABC 时,它起作用了。

以上是关于Oracle XML 解析失败,在 Name 或 Nmtoken 中发现无效字符的主要内容,如果未能解决你的问题,请参考以下文章

oracle plsql:如何解析 XML 并插入到表中

如何解析这个xml文件里边的字符串,谁解答一下,加高分

如何解析XML文件

在 PL/SQL 中解析 XML 或 JSON

oracle PL/SQL解析xml

无法使用 LINQ 解析 XML 文件中的属性