解析XML并通过shell脚本替换特定元素或属性值

khbbv19g  于 2023-03-24  发布在  Shell
关注(0)|答案(5)|浏览(425)

对于下面的xml,我需要将<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

现在我得到了学生的状态为已完成,现在这个值应该改为失败。仅适用于<studentType>Juniour</studentType>。我应该如何编辑xml以便得到它,

<studentFile>
    <student>
        <studentName>CLASSA</studentName>
        <studentStatus>Success</studentStatus>
        <studentActions>
            <studentAction>
                <studentType>Juniour</studentType>
                <studentStatus>Failed</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>

我知道有像xsltproc这样的工具,但不确定我们集群中的所有节点是否都安装了这个工具。
任何帮助将不胜感激。提前感谢!

7cjasjjr

7cjasjjr1#

file.xml中的xmllint更新值:

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"))
t3irkdon

t3irkdon2#

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

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

oxf4rvwz3#

如果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- xpath表达式,用于选择studentStatus元素,该元素具有:

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

dgtucam14#

你可以试试我的Xembly命令行工具:

$ xembly --xml file.xml 'XPATH "/studentFile/student[studentName=\'CLASSA\']/studentActions/studentAction[studentType=\'Juniour\']/studentStatus"; SET "failed";'

Xembly的完整语法是here

dfty9e19

dfty9e195#

使用--shell通过xmlint更新xml文件。

$ xmllint --shell pom.xml
$ cd //*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']
$ set 1.0.0
$ save
$ quit

您可以使用以下命令来进行bash:

xml=$(xmllint --shell pom.xml <<EOF
cd //*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']
set 1.0.0
save -
EOF
)

相关问题