2009-10-20 8 views
14

मैं एक XML फ़ाइल है कि एक सौपानिक संरचना है कि कुछ इस तरह (खरोज महत्वपूर्ण पदानुक्रमित संबंध दिखाने के लिए यहाँ प्रयोग किया जाता है) लग रहा है प्रिंट पार्स करने के लिए अजगर (minidom) का उपयोग कर रहा साथ पार्स:एक्सएमएल अजगर और minidom

My Document 
Overview 
    Basic Features 
    About This Software 
     Platforms Supported 

इसके बजाए, प्रोग्राम नोड्स पर कई बार पुनरावृत्त करता है और निम्नलिखित, प्रिंट डुप्लिकेट नोड्स का उत्पादन करता है। (प्रत्येक यात्रा पर नोड सूची को देखते हुए, यह स्पष्ट है कि ऐसा क्यों करता है, लेकिन मैं नोड सूची मैं तलाश कर रहा हूँ प्राप्त करने के लिए एक रास्ता खोजने के लिए प्रतीत नहीं कर सकते हैं।)

My Document 
Overview 
Basic Features 
About This Software 
Platforms Supported 
Basic Features 
About This Software 
Platforms Supported 
Platforms Supported 

यहाँ XML स्रोत है फ़ाइल:

import xml.dom.minidom 
from xml.dom.minidom import Node 

dom = xml.dom.minidom.parse("test.xml") 
Topic=dom.getElementsByTagName('Topic') 
i = 0 
for node in Topic: 
    alist=node.getElementsByTagName('Title') 
    for a in alist: 
     Title= a.firstChild.data 
     print Title 

मैं 'SubTopic1' और 'की तरह कुछ करने के लिए निचले स्तर के विषय के नाम पर बदलकर घोंसला बनाने से नहीं' विषय 'तत्वों, यह समस्या सुलझा सकता है:

<?xml version="1.0" encoding="UTF-8"?> 
<DOCMAP> 
    <Topic Target="ALL"> 
     <Title>My Document</Title> 
    </Topic> 
    <Topic Target="ALL"> 
     <Title>Overview</Title> 
     <Topic Target="ALL"> 
      <Title>Basic Features</Title> 
     </Topic> 
     <Topic Target="ALL"> 
      <Title>About This Software</Title> 
      <Topic Target="ALL"> 
       <Title>Platforms Supported</Title> 
      </Topic> 
     </Topic> 
    </Topic> 
</DOCMAP> 

यहाँ अजगर कार्यक्रम है SubTopic2 '। लेकिन, मैं विभिन्न तत्व नामों की आवश्यकता के बिना अंतर्निहित एक्सएमएल पदानुक्रमित संरचना का लाभ लेना चाहता हूं; ऐसा लगता है कि मुझे 'टॉपिक' तत्वों को घोंसला करने में सक्षम होना चाहिए और यह जानने का कोई तरीका होना चाहिए कि वर्तमान में कौन सा स्तर 'विषय' मैं देख रहा हूं।

मैंने बिना किसी सफलता के कई अलग-अलग XPath फ़ंक्शंस का प्रयास किया है।

+0

आप पहली बार एक के उत्पादन में चाहते हैं तो आप सिर्फ प्रत्येक तत्व से बाहर पाठ मुद्रित कर सकते हैं - मैं स्पष्ट नहीं कर रहा हूँ कैसे structuting वांछित उत्पादन – Mark

उत्तर

8

getElementsByTagName रिकर्सिव है, आपको सभी मिलान करने वाले टैगनाम के साथ वंशज मिलेगा। चूंकि आपके विषयों में अन्य विषय शामिल हैं जिनमें टाइटल भी हैं, कॉल को कम-से-कम टाइटल कई बार मिलेंगे।

आप सभी मिलान प्रत्यक्ष बच्चों के लिए ही पूछना चाहता हूँ, और आप XPath उपलब्ध नहीं है, तो आप एक साधारण फिल्टर लिख सकते हैं, जैसे .:

def getChildrenByTagName(node, tagName): 
    for child in node.childNodes: 
     if child.nodeType==child.ELEMENT_NODE and (tagName=='*' or child.tagName==tagName): 
      yield child 

for topic in document.getElementsByTagName('Topic'): 
    title= list(getChildrenByTagName('Title'))[0]   # or just get(...).next() 
    print title.firstChild.data 
+0

प्रयास के लिए धन्यवाद प्रभावित करता है। यह काम नहीं किया लेकिन उसने मुझे कुछ विचार दिए। xml.dom.minidom आयात नोड डोम से आयात xml.dom.minidom = xml.dom.minidom.parse ("docmap.xml: निम्न काम करता है (एक ही सामान्य विचार Fwiw, nodeType ELEMENT_NODE है) ") डीईएफ़ getChildrenByTitle (नोड): node.childNodes में बच्चे के लिए : अगर child.localName == 'शीर्षक': उपज बच्चे विषय = विषय में dom.getElementsByTagName ('विषय') नोड के लिए: alist = getChildrenByTitle (नोड) एक अलस्ट के लिए: # शीर्षक = a.firstChild.data शीर्षक = a.childNodes [0] .nodeValue प्रिंट शीर्षक – hWorks

+0

ओह हाँ, मेरा मतलब है कि तत्व बिल्कुल पाठ नहीं है! doh, निश्चित – bobince

7

मुझे यहाँ उस टिप्पणी रखते हैं ..

प्रयास के लिए धन्यवाद। यह काम नहीं किया लेकिन उसने मुझे कुछ विचार दिए। निम्नलिखित काम करता है (एक ही सामान्य विचार; Fwiw, nodeType ELEMENT_NODE है):

def f(elem, level=-1): 
    if elem.nodeName == "Title": 
     yield elem.childNodes[0].nodeValue, level 
    elif elem.nodeType == elem.ELEMENT_NODE: 
     for child in elem.childNodes: 
      for e, l in f(child, level + 1): 
       yield e, l 

हैं:

import xml.dom.minidom 
from xml.dom.minidom import Node 

dom = xml.dom.minidom.parse("docmap.xml") 

def getChildrenByTitle(node): 
    for child in node.childNodes: 
     if child.localName=='Title': 
      yield child 

Topic=dom.getElementsByTagName('Topic') 
for node in Topic: 
    alist=getChildrenByTitle(node) 
    for a in alist: 
#  Title= a.firstChild.data 
     Title= a.childNodes[0].nodeValue 
     print Title 
+0

मैं फ़ंक्शन getTitle (या 'get_title') कहूंगा, और यह सभी तत्काल बच्चे शीर्षक तत्वों को वापस नहीं करेगा, लेकिन केवल पहला (जैसा कि प्रति बच्चे केवल एक शीर्षक होना चाहिए)। –

+0

शायद यही वह है जो मुझे नहीं मिल रहा है। मैं सभी तत्काल बच्चों के खिताब चाहता हूं। शायद एक बेहतर नाम मिल जाएगा TitlesOfChildren। – hWorks

3

आप सूची के माध्यम से चलाने के लिए और इंडेंटेशन स्तर के साथ खिताब पाने के लिए निम्नलिखित जनरेटर इस्तेमाल कर सकते हैं

0123:

import xml.dom.minidom as minidom 
doc = minidom.parse("test.xml") 
list(f(doc)) 

आप निम्नलिखित tuples के साथ एक सूची मिलेगी: यदि आप अपने फाइल के साथ यह परीक्षण

पाठ्यक्रम के ठीक-ठीक होने के लिए यह केवल एक बुनियादी विचार है। यदि आप बस शुरुआत में रिक्त स्थान चाहते हैं तो आप जेनरेटर में सीधे कोड कर सकते हैं, हालांकि स्तर के साथ आपके पास अधिक लचीलापन है। आप स्वचालित रूप से पहले स्तर का पता लगा सकते हैं (यहां यह स्तर -1 को शुरू करने का सिर्फ एक खराब काम है ...)।

+0

जेनरेटर पर आने से पहले मैं पूरी तरह से क्या करने की कोशिश कर रहा हूं। बहुत धन्यवाद। – hWorks

1

Recusive समारोह:

import xml.dom.minidom 

def traverseTree(document, depth=0): 
    tag = document.tagName 
    for child in document.childNodes: 
    if child.nodeType == child.TEXT_NODE: 
     if document.tagName == 'Title': 
     print depth*' ', child.data 
    if child.nodeType == xml.dom.Node.ELEMENT_NODE: 
     traverseTree(child, depth+1) 

filename = 'sample.xml' 
dom = xml.dom.minidom.parse(filename) 
traverseTree(dom.documentElement) 

आपका xml:

<?xml version="1.0" encoding="UTF-8"?> 
<DOCMAP> 
    <Topic Target="ALL"> 
     <Title>My Document</Title> 
    </Topic> 
    <Topic Target="ALL"> 
     <Title>Overview</Title> 
     <Topic Target="ALL"> 
      <Title>Basic Features</Title> 
     </Topic> 
     <Topic Target="ALL"> 
      <Title>About This Software</Title> 
      <Topic Target="ALL"> 
       <Title>Platforms Supported</Title> 
      </Topic> 
     </Topic> 
    </Topic> 
</DOCMAP> 

आपका वांछित आउटपुट:

$ python parse_sample.py 
     My Document 
     Overview 
      Basic Features 
      About This Software 
       Platforms Supported 
2

मुझे लगता है कि मदद कर सकते हैं

import os 
import sys 
import subprocess 
import base64,xml.dom.minidom 
from xml.dom.minidom import Node 
f = open("file.xml",'r') 
data = f.read() 
i = 0 
doc = xml.dom.minidom.parseString(data) 
for topic in doc.getElementsByTagName('Topic'): 
    title= doc.getElementsByTagName('Title')[i].firstChild.nodeValue 
    print title 
    i +=1 

आउटपुट:

My Document 
Overview 
Basic Features 
About This Software 
Platforms Supported 
संबंधित मुद्दे