2016-06-07 1 views
1

Я разбираю xml, у которого есть пользовательское пространство имен, используя lxml. Выдержка из xml приведена ниже.Как сократить запрос фильтра в lxml

<abcd:ABCDCfg xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:abcd="http://www.xyzv.com/abcd"> 
    <abcd:Section name="Features" display-name="Features" desc=“Parameters”> 
    <abcd:Param name=“mode”> 
     <abcd:Type>string</abcd:Type> 
     <abcd:Persistent>true</abcd:Persistent> 
     <abcd:Configurable>true</abcd:Configurable> 
     <abcd:ReadAccess>aup</abcd:ReadAccess> 
     <abcd:WriteAccess>ap</abcd:WriteAccess> 
     <abcd:DisplayName>Mode</abcd:DisplayName> 
    </abcd:Param> 
    </abcd:Section> 
</abcd:ABCDCfg> 

Сейчас, когда я нахожу значение в XML Я использую как этот

sections = xmltree.findall('{http://www.xyzv.com/abcd}Section') 
if (child.tag =='{http://www.xyzv.com/abcd}Param') 

Есть в любом случае в LXML, которая позволит мне использовать LXML без имен. Что-то вроде

sections = xmltree.findall('Section') 
if (child.tag =='Param') 

Это сделает код действительно читаемым. Любая помощь приветствуется.

ответ

1

Если это применимо в вашем случае, вы можете просто удалить все пространства имен из дерева после разбора. Я бы пошел с this solution. Работа образца в Python 3:

import lxml.etree as ET 
from io import BytesIO 


data = b"""<abcd:ABCDCfg xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:abcd="http://www.xyzv.com/abcd"> 
    <abcd:Section name="Features" display-name="Features" desc="Parameters"> 
    <abcd:Param name="mode"> 
     <abcd:Type>string</abcd:Type> 
     <abcd:Persistent>true</abcd:Persistent> 
     <abcd:Configurable>true</abcd:Configurable> 
     <abcd:ReadAccess>aup</abcd:ReadAccess> 
     <abcd:WriteAccess>ap</abcd:WriteAccess> 
     <abcd:DisplayName>Mode</abcd:DisplayName> 
    </abcd:Param> 
    </abcd:Section> 
</abcd:ABCDCfg>""" 

it = ET.iterparse(BytesIO(data)) 
for _, el in it: 
    if '}' in el.tag: 
     el.tag = el.tag.split('}', 1)[1] # strip all namespaces 
root = it.root 

sections = root.findall('Section') 
print(sections) 

Печать:

[<Element Section at 0x10636d0c8>] 

, который означает, что мы можем найти элементы в дереве без указания имен вообще.