2

在 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]);

第二行抛出错误,因为未知前缀 my. 有任何想法吗?

4

1 回答 1

1

除了 PostgreSQL 破坏功能之外,我看不到您遇到的问题。在第一个文件中

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

这个

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

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

# 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)

注意s和如何x绑定到同一个命名空间http://example.com。使用不同的命名空间绑定是令人困惑的,但我只是想向您展示它是如何工作的。

于 2012-12-31T10:11:33.040 回答