cezheng / Fuzi

A fast & lightweight XML & HTML parser in Swift with XPath & CSS support

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using custom namespace prefixes in XPath expressions

mickael-menu-mantano opened this issue · comments

Hello,

First of all, thanks for all the energy spent on this nice library.

I faced two issues working with XPath and namespace prefixes. Both are related to the fact that we don't know exactly how the parsed document will be formatted (using prefixes, or a default namespace using xmlns on a child node).

Let's take for example this expected document:

<?xml version="1.0" encoding="UTF-8"?>
<encryption xmlns:enc="http://www.w3.org/2001/04/xmlenc#">
  <enc:EncryptedData>
  </enc:EncryptedData>
</encryption>
</encryption>

The first issue occurs when the author doesn't use prefixes, but instead default namespace in the child nodes, eg.

<?xml version="1.0" encoding="UTF-8"?>
<encryption>
  <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#">
  </EncryptedData>
</encryption>
</encryption>

In this case, assigning a prefix to a default namespace of a child node doesn't work:

document.definePrefix("enc", defaultNamespace: "http://www.w3.org/2001/04/xmlenc#")
document.xpath("//enc:EncryptedData")  // empty

The second issue happens when the author uses a different prefix than the one expected (this is valid), eg.

<?xml version="1.0" encoding="UTF-8"?>
<encryption xmlns:encrypt="http://www.w3.org/2001/04/xmlenc#">
  <encrypt:EncryptedData>
  </encrypt:EncryptedData>
</encryption>
</encryption>

In this case, we can't register an additional prefix to map to the namespace, like expected:

document.definePrefix("enc", defaultNamespace: "http://www.w3.org/2001/04/xmlenc#")
// still empty
document.xpath("//enc:EncryptedData")
// this works but we shouldn't need to know which prefix the author used in the document
document.xpath("//encrypt:EncryptedData")

To fix those issues, Fuzi should allow to declare the namespace prefixes to be used in XPath expressions. libxml2 already offer this feature but it is not exposed by Fuzi.

I have an upcoming PR with a suggested solution for this problem.

Thanks,
Mickaël