rva4
rva4

Reputation: 43

xpath condition to descendants

I have next xml sample structure

<root>

<rec xmlns="some_url">
<itemNumber>
<number>1</number>
</itemNumber>
</rec>

<rec>
<itemNumber>
<number>2</number>
</itemNumber>
</rec>

<rec>
<itemNumber>
<number>2</number>
</itemNumber>
</rec>

</root>

The problem is that here is xmlns and to find some element I need to find it by local name. For example to find all <rec> elements:

root.xpath("*[local-name() = 'rec']")

To find all itemNumber:

root.xpath("*[local-name() = 'rec']/*[local-name() = 'itemNumber']")

The main barrier is namespaces. But don't advice me on removing namespaces, because my xml document is very huge and it will take additional time. I need to return <rec> elements that fits condition, for example where <number> equals to 2. In this case it will return

<rec>
<itemNumber>
<number>1</number>
</itemNumber>
</rec>

Upvotes: 0

Views: 100

Answers (1)

paul trmbrth
paul trmbrth

Reputation: 20748

The problem is that here is xmlns...

Using namespaces is nothing especially difficult with lxml.

In XPath calls, you just need to pass a namespaces argument with a prefix mapped to this some_url. Then you just need to use that prefix in front of element names.

Example ipython session:

In [1]: import lxml.etree

In [2]: doc = lxml.etree.fromstring("""<root>

<rec xmlns="some_url">
<itemNumber>
<number>1</number>
</itemNumber>
</rec>

<rec>
<itemNumber>
<number>2</number>
</itemNumber>
</rec>

<rec>
<itemNumber>
<number>2</number>
</itemNumber>
</rec>

</root>""")

In [3]: doc.xpath('ns:rec[ns:itemNumber=1]', namespaces={"ns": "some_url"})
Out[3]: [<Element {some_url}rec at 0x7f358cccd2d8>]

In [4]: 

Upvotes: 1

Related Questions