需要帮助的shell脚本查找和XML文件替换值

问题描述:

我有下面的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的新手。我尝试了我的级别以找到现有的问题和答案在*,但coulnd't找到一个相关的。 任何帮助是高度赞赏。

+2

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

+1

请发布一个有效的xml文件和你想要的输出样本到你的问题。 – Cyrus

+3

当您说“我需要使用shell脚本执行”时,您能澄清一下您有什么限制吗?通常这意味着“我不能安装任何额外的软件”,但有时它意味着“perl和python不允许”,甚至“只有shell和简单的命令,如grep和sed以及他们在课堂上教过我们的其他任何东西都是允许的”。 –

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

#!/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输出的服务的人会讨厌它,因为这意味着我们每次更改内容时都会受到投诉,即使新文档是语义上的旧文档的超集。 –

如果你可以使用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样式表,我可以。 –