स्क्रिप्टिंग: XML फ़ाइल के टैग में मान निकालने में सबसे आसान क्या है?


14

मैं एक pom.xml ('प्रोजेक्ट ऑब्जेक्ट मॉडल' मावेन) पढ़ना चाहता हूं और संस्करण की जानकारी निकालना चाहता हूं। यहाँ एक उदाहरण है:

<?xml version="1.0" encoding="UTF-8"?><project 
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany</groupId>
    <artifactId>project-parent</artifactId>
    <name>project-parent</name>
    <version>1.0.74-SNAPSHOT</version>
    <dependencies>
        <dependency>
        <groupId>com.sybase.jconnect</groupId>
        <artifactId>jconnect</artifactId>
        <version>6.05-26023</version>
    </dependency>
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>1.5.2</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jdmk</groupId>
        <artifactId>jmxtools</artifactId>
        <version>1.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.easymock</groupId>
        <artifactId>easymock</artifactId>
        <version>2.4</version>
    </dependency>       
</dependencies>
</project>

मैं ऊपर से '1.0.74-SNAPSHOT' संस्करण कैसे निकाल सकता हूं?

सरल बैश स्क्रिप्टिंग sed या awk का उपयोग करने में सक्षम होना पसंद करेंगे। अन्यथा एक साधारण अजगर को पसंद किया जाता है।

संपादित करें

  1. बाधा

    लिनक्स बॉक्स एक कॉर्पोरेट वातावरण में है, इसलिए मैं केवल उन उपकरणों का उपयोग कर सकता हूं जो पहले से स्थापित हैं (ऐसा नहीं है कि मैं उपयोगिता का अनुरोध नहीं कर सकता हूं जैसे कि xml2, लेकिन मुझे बहुत सारे लाल-टेप से गुजरना होगा)। कुछ समाधान बहुत अच्छे हैं (पहले से ही कुछ नई तरकीबें सीखें), लेकिन वे प्रतिबंधित वातावरण के कारण लागू नहीं हो सकते हैं

  2. अद्यतन xml लिस्टिंग

    मैंने मूल सूची में निर्भरता टैग जोड़ा है। इससे पता चलेगा कि इस मामले में कुछ हैसी समाधान काम नहीं कर सकता है

  3. distro

    मैं उपयोग कर रहा डिस्ट्रो आरएचईएल 4 है


क्या यह stackoverflow.com/questions/29004/… पर्याप्त है?
bbaja42

ज़रुरी नहीं। Xml में बहुत सारे संस्करण टैग हैं (जैसे निर्भरता टैग के तहत)। मैं केवल '/ प्रोजेक्ट / संस्करण' चाहता हूं
एंथनी काँग

कौन से xml से संबंधित टूल और लाइब्रेरी उपलब्ध हैं? क्या jvm- आधारित सॉल्यूशंस ठीक हैं?
वि।

अब तक मैं बता सकता हूं कि xml2, xmlgrep और perl XML मॉड्यूल मौजूद नहीं हैं। अधिकांश यूनिक्स कमांड-लाइन उपयोगिताओं मौजूद हैं। डिस्ट्रो रेडहैट ईएल 4. है
एंथनी कोंग

(मैं एक टिप्पणी नहीं जोड़ सका, इसलिए मुझे एक उत्तर के रूप में उत्तर देना है, कुछ हद तक
ओवरक्लिक

जवाबों:


17

xml2 लाइन-उन्मुख प्रारूप से xml को / में परिवर्तित कर सकता है:

xml2 < pom.xml  | grep /project/version= | sed 's/.*=//'

6

अन्य तरीका: xmlgrep और XPath:

xmlgrep --text_only '/project/version' pom.xml

नुकसान: धीमा


कमांड अपडेट किया गयाxml_grep
GAD3R

6

का उपयोग करते हुए python

$ python -c 'from xml.etree.ElementTree import ElementTree; print ElementTree(file="pom.xml").findtext("{http://maven.apache.org/POM/4.0.0}version")'
1.0.74-SNAPSHOT

का उपयोग करते हुए xmlstarlet

$ xml sel -N x="http://maven.apache.org/POM/4.0.0" -t -m 'x:project/x:version' -v . pom.xml
1.0.74-SNAPSHOT

का उपयोग करते हुए xmllint

$ echo -e 'setns x=http://maven.apache.org/POM/4.0.0\ncat /x:project/x:version/text()' | xmllint --shell pom.xml | grep -v /
1.0.74-SNAPSHOT

cat (//x:version)[1]/text()जब उपयोग xmllintभी काम करता है!
केव

5

लौंग का तरीका विशेष जार फ़ाइल के साथ केवल jvm की आवश्यकता होती है:

java -cp clojure.jar clojure.main -e "(use 'clojure.xml) (->> (java.io.File. \"pom.xml\") (clojure.xml/parse) (:content) (filter #(= (:tag %) :version)) (first) (:content) (first) (println))"

स्केल तरीका:

java -Xbootclasspath/a:scala-library.jar -cp scala-compiler.jar scala.tools.nsc.MainGenericRunner -e 'import scala.xml._; println((XML.load(new java.io.FileInputStream("pom.xml")) match { case <project>{children @ _*}</project> => for (i <- children if (i  match { case <version>{children @ _*}</version> => true; case _ => false;  }))  yield i })(0) match { case <version>{Text(x)}</version> => x })'

Groovy तरीका:

java -classpath groovy-all.jar groovy.ui.GroovyMain -e 'println (new XmlParser().parse(new File("pom.xml")).value().findAll({ it.name().getLocalPart()=="version" }).first().value().first())'

यह कमाल का है! महान विचार!
एंथनी कोंग

4

यहाँ पर्ल में एक विकल्प है

$ perl -MXML::Simple -e'print XMLin("pom.xml")->{version}."\n"'
1.0.74-SNAPSHOT

यह प्रश्नों में संशोधित / विस्तारित उदाहरण के साथ काम करता है जिसमें विभिन्न गहराई पर कई "संस्करण" तत्व हैं।


धीमा, (हालांकि xmlgrep से तेज)
Vi।

3

हैकी तरीका:

perl -e '$_ = join "", <>; m!<project[^>]*>.*\n(?:    |\t)<version[^>]*>\s*([^<]+?)\s*</version>.*</project>!s and print "$1\n"' pom.xml

आवश्यक के सही इंडेंटेशन पर निर्भर करता है <version>


सुझाव के लिए धन्यवाद, लेकिन दुर्भाग्य से यह वापस नहीं आएगा जो मुझे चाहिए। कृपया अद्यतन पोम मॉडल देखें।
एंथनी काँग

"1.0.74-स्नैपशॉट" लौटाता है। ध्यान दें कि मैंने कई <version>चीजों के बारे में पढ़ने के बाद स्क्रिप्ट को बदल दिया ।
वि।

नोट: यह समाधान "केवल मनोरंजन के लिए" प्रदान किया गया है और इसका वास्तविक उत्पाद में उपयोग करने का इरादा नहीं है। बेहतर उपयोग xml2 / xmlgrep / XML :: सरल समाधान।
वि।

धन्यवाद! भले ही यह 'सिर्फ मनोरंजन के लिए' हो, लेकिन यह शायद अब तक का 'सबसे उपयुक्त' समाधान है क्योंकि इसमें निर्भरता की न्यूनतम संख्या है: इसके लिए केवल पर्ल ;-)
एंथनी काँग

जावा से इसे करने के बारे में क्या? पोम फाइलों का उपयोग करने से तात्पर्य है जेवीएम स्थापित होना।
वि।

3

एक बहुत ही अनाड़ी, एक-लाइनर समाधान का काम करें

python -c "from xml.dom.minidom import parse;dom = parse('pom.xml');print [n for n in dom.getElementsByTagName('version') if n.parentNode == dom.childNodes[0]][0].toxml()" | sed -e "s/.*>\(.*\)<.*/\1/g"

अंत में सेड बहुत बदसूरत है, लेकिन मैं केवल माइंडम के साथ नोड के पाठ को प्रिंट करने में सक्षम नहीं था।

_Vi से अपडेट करें :

कम हैथी पायथन संस्करण:

python -c "from xml.dom.minidom import parse;dom = parse('pom.xml');print [i.childNodes.item(0).nodeValue for i in dom.firstChild.childNodes if i.nodeName == 'version'].pop()"

मुझसे अपडेट करें

एक और संस्करण:

    python -c "from  xml.dom.minidom import parse;dom = parse('pom.xml');print [n.firstChild.data for n in dom.childNodes[0].childNodes if n.firstChild and n.tagName == 'version']"

2

XSLT तरीका:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="text"/>

        <xsl:template match="/">
                <xsl:for-each select="*[local-name()='project']">
                    <xsl:for-each select="*[local-name()='version']">
                        <xsl:value-of select="text()"/>
                    </xsl:for-each>
                </xsl:for-each>
        </xsl:template>
</xsl:stylesheet>
xalan -xsl x.xsl -in pom.xml

यदि xsltproc आपके सिस्टम पर है, और यह संभवतः के रूप में libxslt RHEL4 पर है, तो आप इसे और उपरोक्त स्टाइलशीट का उपयोग टैग को आउटपुट करने के लिए कर सकते हैं, अर्थात xsltproc x.xsl prom.xsl।
fpmurphy

2

अगर "xml में बहुत सारे वर्जन टैग हैं" तो आप "सिंपल टूल्स" और रीजैक्स के साथ इसे करना बेहतर समझते हैं, ऐसा नहीं होगा।

इस अजगर की कोशिश करो (कोई निर्भरता नहीं):

from xml.dom.minidom import parse

dom = parse('pom.xml')
project = dom.getElementsByTagName('project')[0]
for node in project.childNodes:
    if node.nodeType == node.ELEMENT_NODE and node.tagName == 'version':
        print node.firstChild.nodeValue

यह स्क्रिप्ट वास्तव में क्या करती है?
साइमन शेहान

यह Python के मिनीडोम कार्यान्वयन का उपयोग करते हुए XML को एक DOM संरचना के रूप में लोड करता है: docs.python.org/library/xml.dom.minidom.html यह विचार उस प्रोजेक्ट को टैग करने के लिए है जो अद्वितीय है और फिर अपने बच्चे के नोड्स पर प्रत्यक्ष (प्रत्यक्ष) केवल childs) टैग को खोजने के लिए <संस्करण> जिसे हम खोज रहे हैं और अन्य टैग उसी स्थान के अन्य नाम के साथ नहीं।
समस_

1

यहाँ एक वन-लाइनर है जो sed का उपयोग कर रहा है:

sed '/<dependencies>/,/<\/dependencies>/d;/<version>/!d;s/ *<\/\?version> *//g' pom.xml

1
तत्वों में मापदंडों की अनुपस्थिति पर निर्भर करता है और यह अतिरिक्त <version>एस केवल निर्भरता के अंदर हो सकता है।
वि।

1

awk बिना किसी अतिरिक्त टूल का उपयोग किए ठीक काम करता है।
cat pod.xml

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.networks.app</groupId>
  <artifactId>operation-platform</artifactId>
  <version>1.0.0</version>
  <packaging>tar.xz</packaging>
  <description>POM was created by Sonatype Nexus</description>
</project>

<packaging>टैग का मान प्राप्त करने का सरल और सुगम तरीका :

cat pod.xml | awk -F'[<>]' '/packaging/{print $3}'

1
यह काम करने के लिए प्रकट होता है, लेकिन सावधान रहें: यह जो करता है वह फ़ील्ड विभाजक (FS) को वर्णों के सेट पर सेट करता है <और>; तब यह "पैकेजिंग" शब्द के साथ सभी पंक्तियों को खोजता है और आपको तीसरा क्षेत्र देता है।
SMerrill8

0
Return_text_val=$(xmllint --xpath "//*[local-name()='$TagElmnt']" $FILE )

यहाँ, यह प्रयास करें:

$TagElmnt - TagName
$FILE - xml file to parse

0

मुझे पता है कि आपका प्रश्न लिनक्स कहता है, लेकिन अगर आपको विंडोज पर किसी भी 3 पार्टी टूल की आवश्यकता के बिना ऐसा करने की आवश्यकता है, जैसे कि आप इसे बैच फ़ाइल में रख सकते हैं, तो पॉवर्सशेल आपके pom.xml फ़ाइल से किसी भी नोड को निकाल सकता है, जैसे :

powershell -Command "& {select-xml //pom:project/pom:properties/pom:mypluginversion -path pom.xml -Namespace  @{pom='http://maven.apache.org/POM/4.0.0'} | foreach {$_.Node.Innerxml}}" > myPluginVersion.txt

पॉवर्सशेल अब खुला स्रोत है और लिनक्स और अन्य प्लेटफार्मों पर चलता है। हम इसे प्राथमिकता के लिए इमारत के लिए उपयोग करते हैं, cygwin और ming64।
चार

0
sed -n "/<name>project-parent/{n;s/.*>\(.*\)<.*/\1/p;q}" pom.xml

-nविकल्प मुद्रण मेल नहीं खाने वाले लाइनों से बचा जाता है; पहला मैच ( /.../) वांछित पाठ के साथ एक से पहले लाइन पर है; nआदेश अगली पंक्ति, करने के लिए छोड़ देता है जहां sएक कैप्चरिंग समूह के माध्यम से अर्क प्रासंगिक जानकारी ( \(...\)), और एक backreference ( \1)। pप्रिंट करता है, बाहर qनिकलता है।


2
क्या आप इसे समझाने के लिए अपने उत्तर का विस्तार कर सकते हैं? धन्यवाद।
fixer1234
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.