2016-08-24 6 views
0

benötigen hierarchische Tags aus XML zu analysieren und die Tag-Wert in den gewünschten AusgabeParse hierarchische XML-Tags

Eingang

<doc> 
<pid id="231"> 
    <label key="">Electronics</label> 
     <desc/> 
     <cid id="122"> 
     <label key="">TV</label> 
     </cid> 
     <desc/> 
     <cid id="123"> 
     <label key="">Computers</label> 
     <cid id="12433"> 
      <label key="">Lenovo</label> 
      </cid> 
      <desc/> 
      <cid id="12434"> 
      <label key="">IBM</label> 
      <desc/> 
      </cid> 
      <cid id="12435"> 
      <label key="">Mac</label> 
      </cid> 
      <desc/> 
    </cid> 
</pid> 
<pid id="7764"> 
    <label key="">Music</label> 
    <desc/> 
     <cid id="1224"> 
     <label key="">Play</label> 
     <desc/> 
      <cid id="341"> 
      <label key="">PQR</label> 
      </cid> 
      <desc/> 
     </cid> 
     <cid id="221"> 
     <label key="">iTunes</label> 
      <cid id="341"> 
      <label key="">XYZ</label> 
      </cid> 
      <desc/> 
      <cid id="515"> 
      <label key="">ABC</label> 
      </cid> 
      <desc/> 
     </cid> 
</pid> 
</doc> 

Ausgabe

Electornics/ 
Electornics/TV 
Electornics/Computers/Lenovo 
Electornics/Computers/IBM 
Electornics/Computers/Mac 
Music/ 
Music/Play/PQR 
Music/iTunes/XYZ 
Music/iTunes/ABC 

zu bekommen Was ich habe, versucht (in Python)

import xml.etree.ElementTree as ET 
import os 
import sys 
import string 

def perf_func(elem, func, level=0): 
    func(elem,level) 
    for child in elem.getchildren(): 
     perf_func(child, func, level+1) 

def print_level(elem,level): 
    print '-'*level+elem.tag 

root = ET.parse('Products.xml') 
perf_func(root.getroot(), print_level) 

# Added find logic 
root = tree.getroot() 

for n in root.findall('doc') 
    l = n.find('label').text 
    print l 

Mit dem obigen Code, ich bin in der Lage, die Knoten und die Levels zu kommen (nur den Tag nicht ihren Wert). Und auch die 1. Ebene aller Labels. Brauchen Sie einen Vorschlag (Perl/Python), wie Sie vorgehen müssen, um die hierarchische Struktur in dem Format zu erhalten, das in Ausgabe erwähnt wird.

+0

Werfen Sie einen Blick auf die etree 'find' &' findall' Funktionen, es einen XPath-Ausdruck – FujiApple

+0

Added den Fund Logik nimmt (die Frage bearbeitet - was ich versucht) ... Sie benötigen einen Vorschlag machen, wie man bekommen die Baumstruktur in dem Format, das in Ausgabe – Debaditya

Antwort

2

Wir werden 3 Stück verwenden: Finden Sie alle Elemente in der Reihenfolge, in der sie auftreten, erhalten Sie die Tiefe von jedem, bauen Sie eine Brotkrume basierend auf der Tiefe und Reihenfolge.

from lxml import etree 
xml = etree.fromstring(xml_str) 
elems = xml.xpath(r'//label') #xpath expression to find all '<label ...> elements 

# counts the number of parents to the root element 
def get_depth(element): 
    depth = 0 
    parent = element.getparent() 
    while parent is not None: 
     depth += 1 
     parent = parent.getparent() 
    return depth 

# build up the bread crumbs by tracking the depth 
# when a new element is entered, it replaces the value in the list 
# at that level and drops all values to the right 
def reduce_by_depth(element_list): 
    crumbs = [] 
    depth = 0 
    elem_crumb = ['']*10 
    for elem in element_list: 
     depth = get_depth(elem) 
     elem_crumb[depth] = elem.text 
     elem_crumb[depth+1:] = ['']*(10-depth-1) 
     # join all the non-empty string to get the breadcrumb 
     crumbs.append('/'.join([e for e in elem_crumb if e])) 
    return crumbs 

reduce_by_depth(elems) 

# output: 
['Electronics', 
'Electronics/TV', 
'Electronics/Computers', 
'Electronics/Computers/Lenovo', 
'Electronics/Computers/IBM', 
'Electronics/Computers/Mac', 
'Music', 
'Music/Play', 
'Music/Play/PQR', 
'Music/iTunes', 
'Music/iTunes/XYZ', 
'Music/iTunes/ABC'] 
+0

erwähnt wird Vielen Dank ... Krümel Logik ist wirklich gut :) – Debaditya