2017-09-26 89 views
0

我有下面的XML格式需要幫助的shell腳本查找和XML文件替換值

<object class="Class A"> 
<directory>someString1</directory> 
<attr> 
    <name>length</name> 
    <value>6</value> 
</attr> 
<attr> 
    <name>parent</name> 
    <value>1</value> 
</attr> 
<attr> 
    <name>Status</name> 
    <value>1</value> 
</attr> 
<attr> 
    <name>className</name> 
    <value>Class A</value> 
</attr> 
<attr> 
    <name>Instance</name> 
    <value>InstanceValue</value> 
</attr> 
</object> 
... 
<object class="Class D"> 
<directory>someString4</directory> 
<attr> 
    <name>length</name> 
    <value>8</value> 
</attr> 
<attr> 
    <name>parent</name> 
    <value>1</value> 
</attr> 
<attr> 
    <name>Status</name> 
    <value>1</value> 
</attr> 
<attr> 
    <name>className</name> 
    <value>Class D</value> 
</attr> 
<attr> 
    <name>Instance</name> 
    <value></value> 
</attr> 
</object> 
.... 

我只需要找到特定的d類對象,並找到實例值是否該對象是空的,如果空填補了作爲論據提供的一些價值。請注意,XML文件中可能有多個對象,並且XML標記名稱和值有相當多的重複。此外,我只需要在suse Linux上使用shell腳本執行此操作。

我是shell腳本編程和SED的新手。我嘗試了我的級別以找到現有的問題和答案在stackoverflow,但coulnd't找到一個相關的。 任何幫助是高度讚賞。

+2

我建議使用XML/HTML解析器(xmlstarlet,xmllint ... )。 – Cyrus

+1

請發佈一個有效的xml文件和你想要的輸出樣本到你的問題。 – Cyrus

+3

當您說「我需要使用shell腳本執行」時,您能澄清一下您有什麼限制嗎?通常這意味着「我不能安裝任何額外的軟件」,但有時它意味着「perl和python不允許」,甚至「只有shell和簡單的命令,如grep和sed以及他們在課堂上教過我們的其他任何東西都是允許的」。 –

回答

0

你可以檢查它是否按你的需要?

#!/bin/bash 

VALUE="NewValue" 
sed -i data.xml -re " 
/Class D/,/<\/object>/ { 
    /<name.*>Instance<\/name>/,/<\/value>/ { 
     s/(<value.*>)(<\/value>)/\1${VALUE}\2/ 
    } 
} 
" 

應該找到你的類,然後找到名爲「實例」,然後插入新的價值,如果沒有價值,否則它不應該做任何

+0

別忘了在運行腳本之前備份你的XML文件,它會在不詢問的情況下更改文件 –

+0

咯咯......如果我聽說過一個'''''''''''''' –

+0

這是一種自信的投票方式天生脆弱。它不能理解註釋,它不能理解CDATA部分,它不能理解命名空間(因此只在文檔的某個部分中,'name'可以真正意味着'{http://example.com/some/命名空間/前綴} name');它甚至不能理解作爲「」超集的'「。當客戶進行這種脆弱的處理時,運行生成XML輸出的服務的人會討厭它,因爲這意味着我們每次更改內容時都會受到投訴,即使新文檔是語義上的舊文檔的超集。 –

2

如果你可以使用xmlstarlet,你可以做例如:

xml ed -L -u "//object[@class='Class D']/attr[name='Instance'][value='']/value" -v "new value" input.xml 

注意:-L就地編輯文件。如果不需要,請將其刪除。

或者,你可以使用xsltproc使用XSLT來處理XML:

xsltproc -o output.xml stylesheet.xsl input.xml 

其中stylesheet.xsl是:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="object[@class='Class D']/attr[name='Instance' and value='']/value"> 
    <xsl:copy> 
     <xsl:text>new value</xsl:text> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

您也可以討論使用xmlstarlet構建XSLT模板,然後可以在沒有安裝xmlstarlet的系統上運行該模板。 –

+0

(OP在問題中指出他們正在使用SuSE,它將xsltproc作爲libxslt包的一部分發布 - 所以它在基線安裝中是開箱即用的。因此,xmlstarlet可能存在也可能不存在在OP的目標環境中,但xsltproc肯定是)。 –

+0

@CharlesDuffy - 好點。我添加了一個xsltproc示例。如果OP希望我討論使用xmlstarlet構建XSLT樣式表,我可以。 –