XML कमांड लाइन प्रोसेसिंग के लिए Grep और Sed इक्वलेंट


147

शेल स्क्रिप्टिंग करते समय, आम तौर पर डेटा सीएसवी की तरह सिंगल लाइन रिकॉर्ड की फाइलों में होगा। यह के साथ इस डेटा को संभालने के लिए वास्तव में आसान है grepऔर sed। लेकिन मुझे एक्सएमएल के साथ अक्सर निपटना पड़ता है, इसलिए मैं कमांड लाइन के माध्यम से उस एक्सएमएल डेटा तक स्क्रिप्ट की पहुंच का एक तरीका चाहूंगा। सबसे अच्छा उपकरण क्या हैं?


xml_grep grepping के लिए ठीक है, जैसा कि stackoverflow.com/a/2222224/871134
Deleplace

जवाबों:


105

मैंने xmlstarlet को इस तरह की चीजों में बहुत अच्छा पाया है।

http://xmlstar.sourceforge.net/

अधिकांश डिस्ट्रो रिपोजिटरी में भी उपलब्ध होना चाहिए। एक परिचयात्मक ट्यूटोरियल यहाँ है:

http://www.ibm.com/developerworks/library/x-starlet.html


1
मैंने सोचा था कि सोर्सफोर्ज साइट पर विंडोज बायनेरिज़ उपलब्ध हैं।
स्टीव बेनेट

XQuery का समर्थन नहीं करता, हालांकि, जहाँ तक मैं बता सकता हूँ।
स्टीव बेनेट

@SteveBennett वास्तव में यह नहीं करता है, लेकिन कच्चे XPath के शीर्ष पर इसे जोड़ने वाली विशेषताएं "grep और sed" के साथ इसे प्रतिस्पर्धी बनाने के लिए पर्याप्त हैं। यदि आप XQuery के फैंसी, फैंसी अच्छाई चाहते हैं ... अच्छी तरह से, यह पर्ल या ऑक के बराबर एक्सएमएल की तरह है। :)
चार्ल्स डफी

36

कुछ होनहार उपकरण:

  • nokogiri : XPath और CSS चयनकर्ताओं का उपयोग करके रूबी में HTML / XML DOM पार्स करना

  • हरिकोट : पदावनत

  • fxgrep : क्वेरी दस्तावेज़ों के लिए अपने स्वयं के XPath- जैसे सिंटैक्स का उपयोग करता है। एसएमएल में लिखा गया है, इसलिए स्थापना मुश्किल हो सकती है।

  • एलटी एक्सएमएल : एक्सएमएल टूलकिट सहित SGML उपकरण, से व्युत्पन्न sggrep, sgsort, xmlnormऔर अन्य। अपने स्वयं के क्वेरी सिंटैक्स का उपयोग करता है। प्रलेखन बहुत औपचारिक है। सी। एलटी XML 2 में लिखे गए XPath, XInclude और अन्य W3C मानकों के समर्थन का दावा करते हैं।

  • xmlgrep2 : XPath के साथ सरल और शक्तिशाली खोज। XML :: LibXML और libxml2 का उपयोग करके पर्ल में लिखा गया है।

  • XQSharp : XQuery, XPath के विस्तार का समर्थन करता है। .NET फ्रेमवर्क के लिए लिखा है।

  • xml-coreutils : Laird Breyer का टूलकिट GNU Coreutils के बराबर। आदर्श टूलकिट में क्या शामिल होना चाहिए, इस पर एक दिलचस्प निबंध में चर्चा की गई ।

  • xmldiff : दो xml फ़ाइलों की तुलना करने के लिए सरल उपकरण।

  • xmltk : को डेबियन, ऑबंटू , फेडोरा या मैकपोर्ट्स में पैकेज नहीं लगता है, 2007 के बाद रिलीज नहीं हुई है, और गैर-पोर्टेबल बिल्ड स्वचालन का उपयोग करता है।

xml-coreutils सबसे प्रलेखित और सबसे UNIX- उन्मुख लगता है।


1
क्या आप रूबी कार्यक्रम के लिए एक रैपर स्क्रिप्ट नहीं बना सकते हैं, और स्क्रिप्ट को हर्टिकॉट में तर्क के सरणी में पास कर सकते हैं? उदाहरण के लिए, PHP शेल स्क्रिप्ट में, निम्नलिखित में से कुछ काम करना चाहिए: <? Php / path / to / hpricot argv?>
alastairs

25

जोसेफ होल्स्टन की उत्कृष्ट सूची में, मैं xpath कमांड-लाइन स्क्रिप्ट जोड़ता हूं जो पर्ल लाइब्रेरी XML :: XPath के साथ आती है। XML फ़ाइलों से जानकारी निकालने का एक शानदार तरीका:

 xpath -q -e '/entry[@xml:lang="fr"]' *xml

3
यह ऑक्स में डिफ़ॉल्ट रूप से स्थापित है, लेकिन -q -eविकल्पों के बिना । उदाहरण, "AndroidManifest.xml" में "मेनिफ़ेस्ट" नोड से विशेषता "पैकेज" मान प्राप्त करें:xpath AndroidManifest.xml 'string(/manifest/@package)' 2> /dev/null
antonj

25

जोड़ी xml2और भी है 2xml। यह XML को संसाधित करने के लिए सामान्य स्ट्रिंग संपादन टूल की अनुमति देगा।

उदाहरण। q.xml:

<?xml version="1.0"?>
<foo>
    text
    more text
    <textnode>ddd</textnode><textnode a="bv">dsss</textnode>
    <![CDATA[ asfdasdsa <foo> sdfsdfdsf <bar> ]]>
</foo>

xml2 < q.xml

/foo=
/foo=   text
/foo=   more text
/foo=   
/foo/textnode=ddd
/foo/textnode
/foo/textnode/@a=bv
/foo/textnode=dsss
/foo=
/foo=    asfdasdsa <foo> sdfsdfdsf <bar> 
/foo=

xml2 < q.xml | grep textnode | sed 's!/foo!/bar/baz!' | 2xml

<bar><baz><textnode>ddd</textnode><textnode a="bv">dsss</textnode></baz></bar>

PS वहाँ भी हैं html2/ 2html


@ जोसेफ होल्स्टन हां। यह एक्सपीथ चीजों के माध्यम से बिना एक्सएमएल के साथ हैकिंग की अनुमति देता है।
वि।

अच्छा! मैं ऐसे उपकरणों पर ध्यान केंद्रित कर रहा था जो एक मध्यवर्ती प्रारूप का उपयोग नहीं करते हैं, लेकिन एक उच्च-निष्ठा, xml के लाइन-उन्मुख प्रतिनिधित्व का विचार वास्तविक grep और sed का उपयोग करने के लिए एक शानदार तरीका लगता है। क्या तुमने pyxie की कोशिश की है? इसकी तुलना कैसे होती है? कोई अन्य पंक्ति उन्मुख अभ्यावेदन? क्या आप इसे एक इकाई (& # 10;) के साथ xml नए सिरे की जगह लेने से बेहतर मानेंगे? यह आपको कम से कम एक ही लाइन पर रिकॉर्ड छड़ी करने देगा। ओह, और क्या आप परियोजना के लिंक को शामिल करने के लिए अपनी पोस्ट को संपादित कर सकते हैं?
यूसुफ होल्स्टेन

@ जोसेफ होल्स्टन नहीं, मुझे नहीं लगता कि xx2 प्रारूप की तुलना में pyxie प्रारूप को अधिक उपयोगी माना जाता है। xml2 नेस्टेड XML तत्वों में "पूर्ण पथ" प्रदान करता है, इसलिए अधिक लाइन-उन्मुख मिलान और प्रतिस्थापन की अनुमति दें। साथ ही 2xmlएक्सएमएल को आंशिक (फिल्टर्ड) xml2आउटपुट से आसानी से रीक्रिएट कर सकते हैं ।
वि।

5
+1 मैं इसे पर्याप्त रूप से नहीं बढ़ा सकता ... cat foo.xml | xml2 | grep /bar | 2xml- आपको मूल के समान संरचना प्रदान करता है, लेकिन "बार" तत्वों को छोड़कर सभी तत्व छीन लिए गए हैं। बहुत बढ़िया।
मोगसी

14

आप xmllint का उपयोग कर सकते हैं:

xmllint --xpath //title books.xml

सबसे डिस्ट्रो के साथ बंडल किया जाना चाहिए, और सिग्विन के साथ भी बंडल किया जाना चाहिए।

$ xmllint --version
xmllint: using libxml version 20900

देख:

$ xmllint
Usage : xmllint [options] XMLfiles ...
        Parse the XML files and output the result of the parsing
        --version : display the version of the XML library used
        --debug : dump a debug tree of the in-memory document
        ...
        --schematron schema : do validation against a schematron
        --sax1: use the old SAX1 interfaces for processing
        --sax: do not build a tree but work just at the SAX level
        --oldxml10: use XML-1.0 parsing rules before the 5th edition
        --xpath expr: evaluate the XPath expression, inply --noout

2
इसके लिए कोई --xpathतर्क नहीं है xmllint: manpagez.com/man/1/xmllint
Miserable Variable

1
@ साझा करने योग्य: मैन पेज गलत है। मैंने अपने संस्करण के लिए सिर्फ मैन पेज देखा: xpath तर्क सूचीबद्ध नहीं है। यह एक प्रलेखन त्रुटि है। इसके बजाय, प्रोग्राम चलाने का प्रयास करें।
डेव जार्विस

2
@MerableVariable --xpathएक हालिया जोड़ और उदाहरण के RHEL 6 संस्करणों में नहीं है xmllint
डैनियल बेक

2
अधिक सटीक होने के लिए, xmllint --xpathlibxml2 2.7.7 (2010 में) में पेश किया गया था।
marbu

9

यदि आप विंडोज पर समाधान की तलाश कर रहे हैं, तो पॉवरशेल ने XML को पढ़ने और लिखने के लिए अंतर्निहित कार्यक्षमता बनाई है।

test.xml:

<root>
  <one>I like applesauce</one>
  <two>You sure bet I do!</two>
</root>

पॉवर्सशेल स्क्रिप्ट:

# load XML file into local variable and cast as XML type.
$doc = [xml](Get-Content ./test.xml)

$doc.root.one                                   #echoes "I like applesauce"
$doc.root.one = "Who doesn't like applesauce?"  #replace inner text of <one> node

# create new node...
$newNode = $doc.CreateElement("three")
$newNode.set_InnerText("And don't you forget it!")

# ...and position it in the hierarchy
$doc.root.AppendChild($newNode)

# write results to disk
$doc.save("./testNew.xml")

testNew.xml:

<root>
  <one>Who likes applesauce?</one>
  <two>You sure bet I do!</two>
  <three>And don't you forget it!</three>
</root>

स्रोत: /server/26976/update-xml-from-the-command-line-windows


Powershell का सहारा लेने से पहले कुछ घंटों के लिए विभिन्न लिनक्स उपकरणों के साथ लड़ाई। मुझे आश्चर्य है कि यह इतना कठिन है - linux cmd-line सामान्य रूप से वास्तव में अच्छा है लेकिन यहाँ एक छेद लगता है। नोट: मेरे लिए उपयोग मामला था: 1) xpath द्वारा नोड्स का पता लगाएं, 2) यदि पाया गया तो हटा दें, 3) नई नोड्स जोड़ें, 4) फ़ाइल सहेजें। मैं सोल कॉन्फ़िगर का एक गुच्छा अद्यतन कर रहा था। अगर किसी को यह करने के लिए एक आसान / विश्वसनीय तरीका पता है कि मैं सभी कान हूँ
रिचर्ड हैर

वाह, यह वास्तव में एक स्वीकार्य समाधान की रेखा तक है। लेकिन ईमानदारी से, मैं शायद इसे स्वीकार करूंगा अगर यह जैसा दिखता था xps $doc .root.one xps $doc 'AppendChild("three")'और xps $doc '.three.set_InnerText("And don't you forget it!")', जो स्पष्ट रूप से हीन है!
जोसेफ होल्स्टन


6

निर्भर करता है कि आप क्या करना चाहते हैं।

XSLT जाने का रास्ता हो सकता है, लेकिन एक सीखने की अवस्था है। Xsltproc का प्रयास करें और ध्यान दें कि आप मापदंडों में हाथ कर सकते हैं।


4

saxon-lintXPath 3.0 / XQuery 3.0 का उपयोग करने की क्षमता के साथ कमांड लाइन से भी है । (अन्य कमांड लाइन उपकरण XPath 1.0 का उपयोग करते हैं)।

उदाहरण :

http / HTML:

$ saxon-lint --html --xpath 'count(//a)' http://stackoverflow.com/q/91791
328

xml:

$ saxon-lint --xpath '//a[@class="x"]' file.xml

4

डी। बोहदन एक खुला स्रोत GitHub रेपो रखता है जो संरचित पाठ टूल के लिए कमांड लाइन टूल की सूची रखता है, वहाँ XML / HTML टूल्स के लिए एक अनुभाग है:

https://github.com/dbohdan/structured-text-tools#xml-html


3

XQuery एक अच्छा समाधान हो सकता है। यह सीखना (अपेक्षाकृत) आसान है और W3C मानक है।

मैं कमांड लाइन प्रोसेसर के लिए XQSharp की सिफारिश करूंगा


1
बेसएक्स में कमांड-लाइन XQuery प्रोसेसर (इसके डेटाबेस मोड के अतिरिक्त) भी है, और मानक के रक्तस्रावी-किनारे संस्करणों के साथ अद्यतित रहता है (XQuery 3.0 के विकसित मसौदे के काफी करीब से)।
चार्ल्स डफी

3

मैंने पहली बार xmlstarlet का उपयोग किया और अभी भी इसका उपयोग कर रहा हूं । जब क्वेरी कठिन हो जाती है, तो मुझे XML की xpath2 और xquery सुविधा समर्थन की आवश्यकता होती है जिसे मैं xidel http://www.videlibri.de/xidel.html की ओर मोड़ता हूँ


1

ग्रीप समतुल्य

आप बैश फ़ंक्शन को परिभाषित कर सकते हैं, "xp" ("xpath") कह सकते हैं जो कुछ python3 कोड को लपेटता है। इसका उपयोग करने के लिए आपको python3 और python-lxml स्थापित करना होगा। लाभ:

  1. regex मिलान जो आप में कमी है जैसे xmllint।
  2. कमांड लाइन पर एक फिल्टर (एक पाइप में) के रूप में उपयोग करें

इस तरह उपयोग करना आसान और शक्तिशाली है:

xmldoc=$(cat <<EOF
<?xml version="1.0" encoding="utf-8"?>
<job xmlns="http://www.sample.com/">programming</job>
EOF
)
selection='//*[namespace-uri()="http://www.sample.com/" and local-name()="job" and re:test(.,"^pro.*ing$")]/text()'
echo "$xmldoc" | xp "$selection"
# prints programming

xp () कुछ इस तरह दिखता है:

xp()
{ 
local selection="$1";
local xmldoc;
if ! [[ -t 0 ]]; then
    read -rd '' xmldoc;
else
    xmldoc="$2";
fi;
python3 <(printf '%b' "from lxml.html import tostring\nfrom lxml import etree\nfrom sys import stdin\nregexpNS = \"http://exslt.org/regular-expressions\"\ntree = etree.parse(stdin)\nfor e in tree.xpath('""$selection""', namespaces={'re':regexpNS}):\n  if isinstance(e, str):\n    print(e)\n  else:\n    print(tostring(e).decode('UTF-8'))") <<< "$xmldoc"
}

सैड समतुल्य

Xq का उपयोग करने पर विचार करें जो आपको jq "प्रोग्रामिंग लैंग्वेज" की पूरी शक्ति प्रदान करता है। यदि आपके पास अजगर-पाइप स्थापित है, तो आप पाइप स्थापित yq के साथ xq स्थापित कर सकते हैं , फिर नीचे उदाहरण में हम "कीप अकाउंट्स" को "कीप अकाउंट्स 2" के साथ बदल रहे हैं:

xmldoc=$(cat <<'EOF'
<resources>
    <string name="app_name">Keep Accounts</string>
    <string name="login">"login"</string>
    <string name="login_password">"password:"</string>
    <string name="login_account_hint">input to login</string>
    <string name="login_password_hint">input your password</string>
    <string name="login_fail">login failed</string>
</resources>
EOF
)
echo "$xmldoc" | xq '.resources.string = ([.resources.string[]|select(."#text" == "Keep Accounts") ."#text" = "Keep Accounts 2"])' -x

-1

JEdit में "XQuery" नामक एक प्लगइन है जो XML दस्तावेजों के लिए क्वेरी कार्यक्षमता प्रदान करता है।

काफी कमांड लाइन नहीं है, लेकिन यह काम करता है!


हालांकि JEdit में फ़ाइल के माध्यम से खोज करने का एक तरीका है, जो इसे एक प्रतियोगी नहीं बनाता है grep(1)
जोसेफ होल्स्टन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.