解析xml并替换特定标签shell脚本

时间:2017-05-14 18:23:29

标签: bash shell xml-parsing xmlstarlet xmllint

对于以下xml,我需要将<studentStatus>的{​​{1}}替换为<studentName>CLASSA</studentName>

<studentStatus>failed</studentStatus>

到目前为止,我得到了什么,

    <studentFile>
                            <student>
                                <studentName>CLASSA</studentName>
                                <studentStatus>Success</studentStatus>
                                <studentActions>
                                    <studentAction>
                                        <studentType>Juniour</studentType>
                                        <studentStatus>Completed</studentStatus>
                                        <studentMsg/>
                                    </studentAction>
                                    <studentAction>
                                        <studentType>HighSchool</studentType>
                                        <studentStatus>Completed</studentStatus>
                                        <studentMsg/>
                                    </studentAction>
                                </studentActions>
                            </student>
                            <student>
                                <studentName>CLASSB</studentName>
                                <studentStatus>Success</studentStatus>
                                <studentActions>
                                    <studentAction>
                                        <studentType>Senior</studentType>
                                        <studentStatus>Completed</studentStatus>
                                    </studentAction>
                                    <studentAction>
                                        <studentType>Middle</studentType>
                                        <studentStatus>Completed</studentStatus>
                                    </studentAction>                         
                                </studentActions>
</student>
    </studentFile>

现在我将学生的状态视为已完成,现在此值应更改为失败。仅适用于xmllint -xpath "/studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType="Juniour"]/studentStatus" myxml.xml 。 我应该如何编辑xml以便将其作为,

<studentType>Juniour</studentType>

可以使用sed完成。我知道有像xsltproc这样的工具但不确定它是否安装在我们集群的所有节点中。

任何帮助将不胜感激。 提前谢谢!

3 个答案:

答案 0 :(得分:6)

使用xmllint中的file.xml更新值:

xmllint --shell file.xml << EOF
cd /studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType='Juniour']/studentStatus
set failed
save
EOF

或没有here document

echo -e "cd /studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType='Juniour']/studentStatus\nset failed\nsave" | xmllint --shell file.xml

更新:在变量中使用bash和XML:

xml=$(xmllint --shell <(echo "$xml") << EOF
cd /studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType='Juniour']/studentStatus
set failed
save -
EOF
)

或没有这里的文件:

xml=$(echo -e "cd /studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType='Juniour']/studentStatus\nset failed\nsave -" | xmllint --shell <(echo "$xml"))

答案 1 :(得分:4)

顾名思义,

xlmlint用于解析和验证XML,而不是编辑它。如果您可以在群集上安装xmlstarlet,则可以执行以下操作:

xmlstarlet ed --update "/studentFile/student[studentName='CLASSA']/studentActions/studentAction[studentType='Juniour']/studentStatus" --value "Failed" *file*

答案 2 :(得分:2)

如果是xmlstarlet(用于查询/编辑/检查/转换的命令行工具包) XML文档)是可访问的:

xmlstarlet ed -u "//studentAction/studentStatus[preceding-sibling::studentType[1][text() = 'Juniour'] \
           and ancestor::student/studentName[text() = 'CLASSA']]" -v failed students.xml

以上将输出需要替换的初始XML文档

命令详情:

ed -u - 编辑/更新模式

//studentAction/studentStatus - 选择studentStatus元素的xpath表达式:

  • preceding-sibling::studentType[1][text() = 'Juniour'] - 前一个兄弟元素studentType,其值为Juniour
  • ancestor::student/studentName[text() = 'CLASSA'] - 最近的元素studentName,其值为CLASSA