2013-03-22 5 views
1

Я пытаюсь разобрать огромный файл. Образец приведен ниже. Я стараюсь взять <Name>, но я не могу Он работает только без этой строкисинтаксический анализ xml by python lxml tree.xpath

<LevelLayout xmlns="http://schemas.datacontract.org/2004/07/ArcherTech.Common.Domain" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 

 

xml2 = '''<?xml version="1.0" encoding="UTF-8"?> 
<PackageLevelLayout> 
<LevelLayouts> 
    <LevelLayout levelGuid="4a54f032-325e-4988-8621-2cb7b49d8432"> 
       <LevelLayout xmlns="http://schemas.datacontract.org/2004/07/ArcherTech.Common.Domain" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
        <LevelLayoutSectionBase> 
         <LevelLayoutItemBase> 
          <Name>Tracking ID</Name> 
         </LevelLayoutItemBase> 
        </LevelLayoutSectionBase> 
       </LevelLayout> 
      </LevelLayout> 
    </LevelLayouts> 
</PackageLevelLayout>''' 

from lxml import etree 
tree = etree.XML(xml2) 
nodes = tree.xpath('/PackageLevelLayout/LevelLayouts/LevelLayout[@levelGuid="4a54f032-325e-4988-8621-2cb7b49d8432"]/LevelLayout/LevelLayoutSectionBase/LevelLayoutItemBase/Name') 
print nodes 

ответ

3

Ваш вложенный LevelLayout XML документ использует пространство имен. Я хотел бы использовать:

tree.xpath('.//LevelLayout[@levelGuid="4a54f032-325e-4988-8621-2cb7b49d8432"]//*[local-name()="Name"]') 

, чтобы соответствовать Name элемент с более коротким выражением XPath (без учета пространства имен в целом).

Альтернативой является использование отображение префикса к-пространства имен и использовать их на тегах:

nsmap = {'acd': 'http://schemas.datacontract.org/2004/07/ArcherTech.Common.Domain'} 

tree.xpath('/PackageLevelLayout/LevelLayouts/LevelLayout[@levelGuid="4a54f032-325e-4988-8621-2cb7b49d8432"]/acd:LevelLayout/acd:LevelLayoutSectionBase/acd:LevelLayoutItemBase/acd:Name', 
    namespaces=nsmap) 
+0

Большое спасибо! Похоже, мне нужно учиться на xpath глубже. – user2200260

0

lxml «s xpath метод имеет namespaces parameter. Вы можете передать им префиксы пространства имен имен dict для пространств имен. Тогда вы можете обратиться построить XPath S, которые используют префикс пространства имен:

xml2 = '''<?xml version="1.0" encoding="UTF-8"?> 
<PackageLevelLayout> 
<LevelLayouts> 
    <LevelLayout levelGuid="4a54f032-325e-4988-8621-2cb7b49d8432"> 
       <LevelLayout xmlns="http://schemas.datacontract.org/2004/07/ArcherTech.Common.Domain" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
        <LevelLayoutSectionBase> 
         <LevelLayoutItemBase> 
          <Name>Tracking ID</Name> 
         </LevelLayoutItemBase> 
        </LevelLayoutSectionBase> 
       </LevelLayout> 
      </LevelLayout> 
    </LevelLayouts> 
</PackageLevelLayout>''' 

namespaces={'ns': 'http://schemas.datacontract.org/2004/07/ArcherTech.Common.Domain', 
      'i': 'http://www.w3.org/2001/XMLSchema-instance'} 

import lxml.etree as ET 
# This is an lxml.etree._Element, not a tree, so don't call it tree 
root = ET.XML(xml2) 

nodes = root.xpath(
    '''/PackageLevelLayout/LevelLayouts/LevelLayout[@levelGuid="4a54f032-325e-4988-8621-2cb7b49d8432"] 
     /ns:LevelLayout/ns:LevelLayoutSectionBase/ns:LevelLayoutItemBase/ns:Name''', namespaces = namespaces) 
print nodes 

дающий

[<Element {http://schemas.datacontract.org/2004/07/ArcherTech.Common.Domain}Name at 0xb74974dc>] 
Смежные вопросы