2012-02-08 14 views
9

से मूल xml पार्सिंग करने का सबसे आसान तरीका मैं xml फ़ाइलों की खोज कर रहा हूं जिनमें कुछ गुण हैं। उदाहरण के लिए, फ़ाइलों को निम्नलिखित पैटर्न होते हैं:यूनिक्स कमांड लाइन

<param-value> 
    <name>Roles</name> 
    <description>some description</description> 
    <value>asdf</value> 
</param-value> 

और साथ बाहर फ़ाइल नाम मुद्रित: इस तरह फ़ाइलों के लिए

<param-value> 
    <name>Hosts</name> 
    <description>some description</description> 
    <value></value> 
</param-value> 

, मैं इस तरह के रूप में, एक और टैग के मान को पार्स करने के लिए करना चाहते हैं "asdf" के साथ। कमांड लाइन से इसे पूरा करने का सबसे आसान तरीका क्या है?

एक दृष्टिकोण जो मैं सोच रहा था कि मिलान करने वाली फ़ाइलों को फ़िल्टर करने के लिए -l विकल्प के साथ grep का उपयोग कर रहा था, और फिर भूमिकाओं के मूल्य को निकालने के लिए xargs grep का उपयोग कर रहा था। हालांकि, grep बहु-पंक्ति regexes के साथ अच्छी तरह से काम नहीं करता है। मैंने एक और सवाल देखा जो दिखाता है कि यह -Pzo विकल्पों के साथ किया जा सकता है, लेकिन मेरे मामले में काम करने के लिए कोई भाग्य नहीं मिला। क्या कोई आसान दृष्टिकोण है?

+0

कोई विशेष कारण है कि आप इस तरह के पर्ल के रूप में एक पटकथा भाषा का उपयोग नहीं करना चाहते है? – Tom

+0

नहीं, एक पर्ल समाधान बहुत अच्छा होगा, अधिमानतः एक कॉम्पैक्ट एक-लाइनर, लेकिन मुझे इसे लिखने के लिए सबसे अच्छा तरीका नहीं पता है। – jonderry

+0

यह समाधान उपयोगी होगा जो केवल सबसे बुनियादी उपकरण के साथ चलता है, हालांकि xmlstarlet, xpath, और perl का xpath मॉड्यूल उस सिस्टम पर स्थापित नहीं है जिस पर मैं खोज करने जा रहा हूं। – jonderry

उत्तर

2

मेरे लिए सबसे आसान आदेश कमांड लाइन से Saxon का उपयोग करना है।

यहां XPath on the command line का उपयोग करने का एक उदाहरण दिया गया है। यह, एक शेल स्क्रिप्ट के साथ संयुक्त, वही करेगा जो आप पूछ रहे हैं।

+0

यह सबसे पोर्टेबल समाधान जैसा दिखता है जो मैं हूं जरुरत। –

0

मुझे आपकी समस्या के माध्यम से अधिक सावधानीपूर्वक काम करने की उम्मीद थी, लेकिन मुझे समय से बाहर निकलना है, क्षमा करें।

वैसे भी - perl में XML पढ़ने के लिए कुछ बहुत अच्छे मॉड्यूल हैं।

विशेष रूप से, निम्न आलेख, perl and xml on the command line, शायद रुचि का है।

0

मैं आमतौर पर पर्ल के XML::XSH2 का उपयोग करता हूं। आप एक्सएमएल फाइलों को इंटरैक्टिव रूप से संसाधित कर सकते हैं, या इसे स्क्रिप्ट कर सकते हैं।

for my $file in { glob "*.xml" } { 
    open $file ; 
    my $param_value = //param-value[name="Hosts"] ; 
    if $param_value echo $file $value/value ; 
} 
12

निम्नलिखित linux कमांड एक्सएमएल फाइल मिलान के लिए एक्सएमएल फ़ाइल

for xml in `find . -name "*.xml"` 
do 
echo $xml `xmllint --xpath "/param-value/value/text()" $xml`| awk 'NF>1' 
done 

उदाहरण आउटपुट के भीतर निर्दिष्ट मान तक पहुँचने के लिए XPath का उपयोग करता है:

./test1.xml asdf 
./test4.xml 1234 
लिपि (untested) की तरह कुछ होगा
1

मैंने बुनियादी perl/awk कार्यक्षमता (मूल रूप से टैग के एक गरीब व्यक्ति की पार्सिंग) का उपयोग करके कुछ समाधान किए। यदि आपको केवल मूल perl/awk कार्यक्षमता का उपयोग करके कोई सुधार दिखाई देता है, तो मुझे बताएं। मैंने एक विशेष टैग देखने के साथ ध्वज स्थापित करके मल्टीलाइन नियमित अभिव्यक्तियों से निपटने से परहेज किया। बेकार की तरह लेकिन यह काम करता है।

पर्ल:

perl -ne '$h = 1 if m/Host/; $r = 1 if m/Role/; if ($h && m/<value>/) { $h = 0; print "hosts: ", $_ =~ /<value>(.*)</, "\n"}; if ($r && m/<value>/) { $r = 0; print "\nrole: ", $_ =~ /<value>(.*)</, "\n" }' 

awk:

awk '/Host/ {h = 1} /Role/ {r = 1} h && /<value>/ {h = 0; match($0, "<value>(.*)<", a); print "hosts: " a[1]} r && /<value>/ {r = 0; match($0, "<value>(.*)<", a); print "\nrole: " a[1]}' 
+4

डाउनवोट, कृपया बताएं कि आपने क्यों गिराया। – jonderry

1
$ xmlstarlet ed -u /param-value/name -v Roles -u /param-value/value -v asdf data.xml 

<?xml version="1.0"?> 
<param-value> 
    <name>Roles</name> 
    <description>some description</description> 
    <value>asdf</value> 
</param-value> 
संबंधित मुद्दे