在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]);
第二行抛出错误,因为我的前缀未知。有什么想法吗?
答案 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)
请注意s
和x
如何绑定到同一名称空间http://example.com
。使用不同的命名空间绑定令人困惑,但我只是想告诉你它是如何工作的。