XML कमांड लाइन (शेल स्क्रिप्ट) हेरफेर


9

शेल स्क्रिप्ट में कमांड लाइन से XML को हेरफेर कैसे करें?

सारणीबद्ध डेटा को हेरफेर करने, पर्यावरण चर को प्रतिस्थापित करने या रेगेक्स के साथ पाठ अंशों को बदलने के लिए कई कमांड हैं, लेकिन मुझे एक्सएमएल के लिए कुछ भी नहीं मिला है।

मेरी बिल्ड स्क्रिप्ट को xml दस्तावेज़ के मुख्य टैग के भीतर सामग्री के साथ एक टैग सम्मिलित करने की आवश्यकता है, और मुझे लगता है कि इस उद्देश्य के लिए ओएस में जावा, पर्ल या अजगर स्थापित करने के लिए एक ओवरकिल है (मेरी स्क्रिप्ट गेटर छवियों के साथ gitlab में की गई है, इसलिए मावेन में उपलब्ध टूल के साथ मेरी नौकरी: 3.5-jdk-8 छवि एक सपना होगी)।

मैं XML के साथ छेड़खानी नहीं करना चाहता, हालांकि मेरी बिल्ड स्क्रिप्ट में यह काम करेगा, क्योंकि यह बुराई है

उदाहरण: मेरे पास निम्नलिखित xml है:

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>  
  <!-- a lot of other tags-->
</project>  

और मैं निम्नलिखित ब्लॉक सम्मिलित करना चाहता हूं:

<distributionManagement>
    <repository>
        <id>private-releases</id>
        <url>https://my.private.server.com/nexus/repository/maven-releases/</url>
    </repository>
</distributionManagement>

प्रोजेक्ट टैग के अंदर (और यह पूरी तरह से कोई फर्क नहीं पड़ता अगर यह शुरुआत या अंत में होगा।


अपना इनपुट xml और अपेक्षित आउटपुट पोस्ट करें
RomanPerekhrest

तो विशिष्ट आवश्यकताएं XML पार्सर के लिए होती हैं जिन्हें कमांड लाइन से लगाया जा सकता है जो कि किसी भी प्रमुख स्क्रिप्टिंग भाषाओं में लागू नहीं होती है, लेकिन एक फ्रीस्टैंडिंग C या C ++ (या अन्य संकलित) उपयोगिता है?
Kusalananda

@ कुसलंडा ने निर्दिष्ट किया है कि मैं डॉकटर कंटेनरों के भीतर स्कैट्स चला रहा हूं, इसलिए मेरे लिए यह सबसे महत्वपूर्ण है कि जितना संभव हो उतना कम डॉकटर छवि में जोड़ें।
9ilsdx 9rvj 0lo

यदि आपके पास मावेन और एक jdk के साथ एक छवि है, तो जावा मुझे सबसे अच्छा विकल्प लगता है .... आप इस मामले में जावा हैवीवेट क्यों मानते हैं?
डैनियल प्रीडन

यह शायद स्टैक ओवरफ्लो पर यह सवाल पूछने और साथ टैग करने के लायक है maven- मुझे संदेह है कि ऐसा करने का एक बेहतर तरीका है जो आप मावेन के भीतर ही करने की कोशिश कर रहे हैं।
डैनियल प्राइडेन

जवाबों:


10

XMLStarlet ( http://xmlstar.sourceforge.net/overview.php ) सी और उपयोग करता है में लिखा है libxml2और libxslt

XML दस्तावेज दिया

<?xml version="1.0"?>
<root>
  <tag>data</tag>
</root>

एक सबनॉड का rootउपयोग करके डाला जा सकता है

xml ed -s '/root' -t elem -n 'newtag' -v 'newdata' file.xml

जो पैदा करता है

<?xml version="1.0"?>
<root>
  <tag>data</tag>
  <newtag>newdata</newtag>
</root>

कई चीजों को सम्मिलित करना ( file.xmlयहाँ शीर्ष पर मूल का उपयोग करना ):

xml ed -s '/root' -t elem -n 'newtag' \
       -s '/root/newtag' -t elem -n 'subtag' -v 'subdata' file.xml

यह पैदा करता है

<?xml version="1.0"?>
<root>
  <tag>data</tag>
  <newtag>
    <subtag>subdata</subtag>
  </newtag>
</root>

प्रश्न में उदाहरण के लिए:

xml ed -N x="http://maven.apache.org/POM/4.0.0" \
       -s '/x:project' -t elem -n 'distributionManagement' \
       -s '/x:project/distributionManagement' -t elem -n 'repository' \
       -s '/x:project/distributionManagement/repository' -t elem -n 'id' \
         -v 'private-releases' \
       -s '/x:project/distributionManagement/repository' -t elem -n 'url' \
         -v 'https://my.private.server.com/nexus/repository/maven-releases/' \
    file.xml

परिणाम:

<?xml version="1.0"?>
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <!-- a lot of other tags-->
  <distributionManagement>
    <repository>
      <id>private-releases</id>
      <url>https://my.private.server.com/nexus/repository/maven-releases/</url>
    </repository>
  </distributionManagement>
</project>

XML में किसी स्थान पर पहले से तैयार XML फ़ाइल सम्मिलित करना:

मूल XML को प्रश्न से अलग मानकर file.xmlनए distributinManagementनोड में जाने वाले अतिरिक्त बिट्स new.xml(लेकिन स्वयं नोड टैग नहीं ) में हैं, कोई रूट नोड में सम्मिलित करने के लिए निम्न कार्य कर सकता हैnew.xml :

xml ed -N x="http://maven.apache.org/POM/4.0.0" \
       -s '/x:project' -t elem -n 'distributionManagement' \
       -v "$(<new.xml)" file.xml | xml unesc | xml fo

XMLStarlet स्वचालित रूप से उन डेटा से बच जाएगा जो भागने की जरूरत है, जैसे कि <और >वर्ण। xml unescबिट unescapes डाला डेटा (यह वास्तव में पूरे दस्तावेज है, जो या एक मुद्दा नहीं हो सकता unescapes), और xml foreformats जिसके परिणामस्वरूप XML दस्तावेज़।

परिणाम है

<?xml version="1.0"?>
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <!-- a lot of other tags-->
  <distributionManagement>
    <repository>
      <id>private-releases</id>
      <url>https://my.private.server.com/nexus/repository/maven-releases/</url>
    </repository>
  </distributionManagement>
</project>

मैं इसे इस तरह से करने के बारे में थोड़ा असहज हूं, "लेकिन यह काम करता है"।

StackOverflow पर यह संबंधित प्रश्न भी देखें: /programming/29298507/xmlstarlet-xinclude-xslt


यह दिलचस्प लगता है, हालांकि एक से अधिक टैग डालने के लिए वाक्यविन्यास काफी लंबा है। केवल उस ubuntu में इसे 'xmlstarlet' नाम दिया गया है। क्या टैग के रूप में अन्य फ़ाइल की सामग्री सम्मिलित करना संभव है, यह मानते हुए कि सामग्री एक वैध xml है?
9ilsdx 9rvj 0lo

@ 9ilsdx9rvj0lo अपडेट किया गया उत्तर देखें।
Kusalananda

"यह वास्तव में पूरे दस्तावेज़ को हटा देता है, जो एक मुद्दा हो सकता है या नहीं"। हां बड़े पैमाने पर मुद्दा, सभी मौजूदा & amp; XML अनएन्कोडेड होने के कारण वैध नहीं रह गया :(
लूटना

1

मुझे लगता है कि इस उद्देश्य के लिए ओएस में जावा, पर्ल या अजगर स्थापित करने के लिए एक ओवरकिल है (मेरी स्क्रिप्ट docker छवियों के साथ gitlab में की गई है, इसलिए मावेन में उपलब्ध टूल के साथ मेरा काम करना: 3.5-jdk-8 छवि एक सपना होगा)।

यह शायद अभी भी ओवरकिल है, लेकिन अगर आप केवल कंटेनर के आकार से संबंधित हैं, तो आप बहुत हल्की भाषा जैसे कि लुआ या गुइले का उपयोग कर सकते हैं।

लुआ डॉक्स से:

एक आवेदन में Lua जोड़ने से यह फूल नहीं है। Lua 5.3.4 के लिए टारबॉल, जिसमें स्रोत कोड और प्रलेखन शामिल हैं, 297K संपीड़ित और 1.1M असम्पीडित लेता है। स्रोत में सी की लगभग 24000 लाइनें शामिल हैं। 64-बिट लिनक्स के तहत, सभी मानक लुआ पुस्तकालयों के साथ निर्मित Lua दुभाषिया 246K लेता है और Lua पुस्तकालय 421K लेता है।


यह केवल कंटेनर में LUA जोड़ने के लिए विचार करने के लायक है, टिप के लिए धन्यवाद।
9ilsdx 9rvj 0lo
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.