2011-09-24 5 views
6

के साथ विशिष्ट XML नोड मानों को संग्रहीत करना मेरे पास एक बड़ी XML फ़ाइल है जिसे मुझे xmlEventParse in R के साथ पार्स करने की आवश्यकता है। दुर्भाग्य से ऑनलाइन उदाहरणों की तुलना में अधिक जटिल उदाहरण हैं, और मैं मिलान किए गए नोड टेक्स्ट (विशेषता नहीं) को स्टोर करने के लिए एक मिलान नोड टैग को ध्वजांकित करना चाहता हूं, प्रत्येक पाठ को एक अलग सूची में संग्रहीत करें, नीचे दिए गए कोड में टिप्पणियां देखें:आर के xmlEventParse

library(XML) 
z <- xmlEventParse(
    "my.xml", 
    handlers = list(
     startDocument = function() 
     { 
       cat("Starting document\n") 
     }, 
     startElement = function(name,attr) 
     { 
       if (name == "myNodeToMatch1"){ 
        cat("FLAG Matched element 1\n") 
       } 
       if (name == "myNodeToMatch2"){ 
        cat("FLAG Matched element 2\n") 
       } 
     }, 
     text   = function(text) { 
       if (# Matched element 1 ....) 
        # Store text in element 1 list 
       if (# Matched element 2 ....) 
        # Store text in element 2 list 
     }, 
     endDocument  = function() 
     { 
       cat("ending document\n") 
     } 
    ), 
    addContext = FALSE, 
    useTagName = FALSE, 
    ignoreBlanks = TRUE, 
    trim = TRUE) 
z$ ... # show lists ?? 

मेरा सवाल है, आर में इस ध्वज को कैसे कार्यान्वित करें (पेशेवर तरीके से :)? प्लस: मिलान करने के लिए एन मनमानी नोड्स का मूल्यांकन करने के लिए सबसे अच्छा विकल्प क्या है ... यदि नाम = "myNodeToMatchN" ... नोड्स केस मिलान से परहेज करते हैं?

my.xml हो सकता है सिर्फ एक अनुभवहीन एक्सएमएल तरह

<A> 
    <myNodeToMatch1>Text in NodeToMatch1</myNodeToMatch1> 
    <B> 
    <myNodeToMatch2>Text in NodeToMatch2</myNodeToMatch2> 
    ... 
    </B> 
</A> 
+0

अच्छा होगा अगर हमारे पास "my.xml" काम करने की कोशिश करने के लिए आसान था ... –

उत्तर

6

मैं fileNameexample(xmlEventParse) से एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण के रूप में इस्तेमाल करेंगे। इसमें record टैग हैं जिनमें id और वह टेक्स्ट है जिसे हम निकालना चाहते हैं। handler का उपयोग करने के बजाय, मैं branches तर्क के बाद जाऊंगा। यह एक हैंडलर की तरह है, लेकिन केवल तत्व के बजाय पूर्ण नोड तक पहुंच है। विचार यह है कि हमारे पास जमा किए गए डेटा को रखने के लिए एक जगह है, और उस XML दस्तावेज़ की प्रत्येक शाखा को संसाधित करने के लिए एक फ़ंक्शन है जिसमें हम रुचि रखते हैं। तो चलो बंद करने को परिभाषित करके शुरू करें - हमारे उद्देश्यों के लिए, एक फ़ंक्शन कार्यों

ourBranches <- function() { 

हम परिणाम हम जमा स्टोर करने के लिए एक जगह की जरूरत है की एक सूची देता है, एक ऐसा माहौल को चुनने ताकि प्रविष्टि बार लगातार कर रहे हैं (नहीं एक सूची है, जो हम करने के लिए संलग्न करने के लिए होता है और स्मृति अक्षम होगा)

store <- new.env() 

ईवेंट पार्सर मिलान करने वाले टैग की खोज होने पर कार्यों की सूची की उम्मीद कर रहा है। हमें record टैग में रुचि है। हमारे द्वारा लिखे गए फ़ंक्शन को XML दस्तावेज़ का नोड प्राप्त होगा। हम एक तत्व id निकालना चाहते हैं जिसे हम नोड में (टेक्स्ट) मानों को संग्रहीत करने के लिए उपयोग करेंगे। हम इन्हें अपने स्टोर में जोड़ते हैं।

record <- function(x, ...) { 
     key <- xmlAttrs(x)[["id"]] 
     value <- xmlValue(x) 
     store[[key]] <- value 
    } 

एक बार दस्तावेज़ संसाधित किया जाता है, हम अपने परिणाम प्राप्त करने के लिए एक सुविधाजनक तरीका चाहते हैं, इसलिए हम दस्तावेज़ में नोड्स के हमारे अपने उद्देश्यों के लिए एक समारोह जोड़ने के लिए, स्वतंत्र

getStore <- function() as.list(store) 

और उसके बाद कार्यों की एक सूची वापस लौट कर बंद खत्म

list(record=record, getStore=getStore) 
} 

यहाँ एक मुश्किल अवधारणा है कि वातावरण में एक समारोह परिभाषित किया गया है समारोह का हिस्सा है, इसलिए हर बार हम कहते हैंहैहमें अपने परिणामों को रखने के लिए और एक नया वातावरण store फ़ंक्शंस की एक सूची प्राप्त होती है। उपयोग करने के लिए, हमारी फ़ाइल पर xmlEventParse को ईवेंट हैंडलर के खाली सेट के साथ, और हमारे एकत्रित स्टोर तक पहुंचें।

> branches <- ourBranches() 
> xmlEventParse(fileName, list(), branches=branches) 
list() 
> head(branches$getStore(), 2) 
$`Hornet Sportabout` 
[1] "18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 " 

$`Toyota Corolla` 
[1] "33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 " 
2

जो दूसरों M.Morgan से lear की कोशिश कर सकते के लिए - यहाँ पूरा कोड

fileName = system.file("exampleData", "mtcars.xml", package = "XML") 

ourBranches <- function() { 
    store <- new.env() 
    record <- function(x, ...) { 
    key <- xmlAttrs(x)[["id"]] 
    value <- xmlValue(x) 
    store[[key]] <- value 
    } 
    getStore <- function() as.list(store) 
    list(record=record, getStore=getStore) 
} 

branches <- ourBranches() 
xmlEventParse(fileName, list(), branches=branches) 
head(branches$getStore(), 2) 
0

शाखाओं विधि घटनाओं के क्रम बनाए रखने नहीं करता है। दूसरे शब्दों में, शाखाओं में 'रिकॉर्ड' का क्रम $ getStore() स्टोर मूल xml फ़ाइल से अलग है। दूसरी तरफ, हैंडलर विधियां ऑर्डर को सुरक्षित रख सकती हैं।

fileName <- system.file("exampleData", "mtcars.xml", package="XML") 
records <- new('list') 
variable <- new('character') 
tag.open <- new('character') 
nvar <- 0 
xmlEventParse(fileName, list(startElement = function (name, attrs) { 
    tagName <<- name 
    tag.open <<- c(name, tag.open) 
    if (length(attrs)) { 
    attributes(tagName) <<- as.list(attrs) 
    } 
}, text = function (x) { 
    if (nchar(x) > 0) { 
    if (tagName == "record") { 
     record <- list() 
     record[[attributes(tagName)$id]] <- x 
     records <<- c(records, record) 
    } else { 
     if(tagName == 'variable') { 
     v <- x 
     variable <<- c(variable, v) 
     nvar <<- nvar + 1 
     } 
    } 
    } 
}, endElement = function (name) { 
    if(name == 'record') { 
    print(paste(tag.open, collapse='>')) 
    } 
    tag.open <<- tag.open[-1] 
})) 

head(records,2) 
$``Mazda RX4`` 
[1] "21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4" 

$`Mazda RX4 Wag` 
[1] "21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4" 

variable 
[1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear" "carb" 

संचालकों का उपयोग करने का एक अन्य लाभ यह है कि एक सौपानिक संरचना पर कब्जा कर सकते हैं: यहाँ कोड है। दूसरे शब्दों में, पूर्वजों को भी बचाया जा सकता है। इस प्रक्रिया के प्रमुख बिंदुओं में से एक वैश्विक चर का उपयोग है, जिसे "< < -" के बजाय "< -" के साथ असाइन किया जा सकता है।