Postgresql 9.2 xml名称空间前缀错误

时间:2012-12-26 15:40:05

标签: xml postgresql

在PostgreSQL 9.1上,我可以执行这两个查询,没有任何错误,结果正确:

SELECT xpath('/a', '<a s:dd="11"><c>test</c></a>')
SELECT xpath('/a', '<a s:dd="11"><c>test</c></a>',ARRAY[ARRAY['s', 'http://example.com']])

在PostgreSQL 9.2上,相同的查询会抛出错误:

ERROR:  could not parse XML document
DETAIL:  line 1: Namespace prefix s for dd on a is not defined

只有这个查询才能正常工作:

SELECT xpath('/a', '<a xmlns:s="ddd" s:dd="11"><c>test</c></a>')

如果不修改XML代码,我如何解析XML文件?

当我想对xml元素进行xpath查询时出现问题,从先前的查询中恢复。

例如xml文档:

 <some xmlns:my="somens">
      <a>
          <b my:param="11" />
      </a>
 </some>

我想做这样的事情:

 elem = xpath('/a',doc);
 elem2= xpath('//b',elem[0]);

第二行抛出错误,因为我的前缀未知。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我没有看到除了PostgreSQL破解功能之外你遇到的问题。在第一份文件中

这是严格的XML解析器的预期行为。 PostgreSQL改变行为的事实很糟糕,但我想我们只需处理一些事情。

SELECT xpath('/a', '<a s:dd="11"><c>test</c></a>')

失败,因为未在XML文档中声明s命名空间。这有效:

# SELECT xpath('/a', '<a xmlns:s="http://example.com" s:dd="11"><c>..</c></a>');
                      xpath                       
--------------------------------------------------
 {"<a xmlns:s=\"http://example.com\" s:dd=\"11\">+
   <c>..</c>                                   +
 </a>"}
(1 row)

你在这做什么:

SELECT xpath('/a', '<a xmlns:s="http://example.com" s:dd="11"><c>..</c></a>',
    ARRAY[ARRAY['s', 'http://example.com']]);

是将s命名空间绑定到http://example.com,使您能够在该命名空间中运行xpath表达式。观察:

这是原始查询,但a标记位于http://example.com命名空间中。当您在默认命名空间中查询/a元素时,您的查询(a)与任何文档都不匹配:

# SELECT xpath('/a', '<s:a xmlns:s="http://example.com" s:dd="11"><c>test</c></s:a>');
 xpath 
-------
 {}
(1 row)

然而,这会选择根元素:

# SELECT xpath('/x:a', '<s:a xmlns:s="http://example.com" s:dd="11"><c>..</c></s:a>',
    ARRAY[ARRAY['x', 'http://example.com']]);
                       xpath                        
----------------------------------------------------
 {"<s:a xmlns:s=\"http://example.com\" s:dd=\"11\">+
   <c>test</c>                                     +
 </s:a>"}
(1 row)

请注意sx如何绑定到同一名称空间http://example.com。使用不同的命名空间绑定令人困惑,但我只是想告诉你它是如何工作的。