如何使用 xmlstarlet 和 bash 检查子节点是否存在?

How to check if a subnode exists using xmlstarlet and bash?

我有一个脚本正在向我的 XML 文件添加一个子节点,它工作正常。

问题是我 运行 这个脚本很多时间,我只想添加我的子节点一次,所以我需要检查它是否存在,如果它不存在,它是否什么也不做'不存在 我想创建它。 (在我的示例中创建名称为 66.66.66 的子节点)

#!/bin/bash
LOCK_BRANCH="66.66.66" 
#Adding a new subnode to certain nodes
xmlstarlet ed -L --subnode  "/configurations/rules" --type elem -n rule config.xml

#Adding text to the new node
xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n name -v "$LOCK_BRANCH" config.xml
xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n repo -v "mqm" config.xml
xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n branch -v "refs/heads/12.55.99" config.xml
xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n emailTo -v "imichael@gmail.com" config.xml
xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n path -v "Server/.*/schema/v.*/.*/.*-dbSchemaDescriptor\.xml,Server/.*/resources/" config.xml

这是原始 XML 文件:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<configurations>
    <smtpHost>smtp3.gmail.com</smtpHost>
    <smtpPort>25</smtpPort>
    <emailFrom>GitPushNotifier@gmail.com</emailFrom>
    <emailSubject>Push notification</emailSubject>
    <!-- Stash general URL-->
    <gitViewerURL>http://server0005.gmail.net:7990/projects/</gitViewerURL>
  <rules>
    <rule>
        <name>test_12.55.4</name>
        <repo>test</repo>
        <branch>refs/heads/12.55.4</branch>
        <emailTo>test@gmail.com</emailTo>
        <path>Server/.*/resources/schema/v.*/.*/.*-dbSchemaDescriptor\.xml,Server/.*/resources/SpringIOC/dataupgrader/v.*/.*/.*-dataUpgrader\.xml,Server/.*/java/com/hp/test/dataupgrader/v.*/.*/.*\.java,Server/.*/resources/indexes/v.*/.*\.index,Server/.*/resources/SpringIOC/vanilla/.*\.xml</path>
    </rule>
    <rule>
        <name>test_12.55.10</name>
        <repo>test</repo>
        <branch>refs/heads/12.55.10</branch>
        <emailTo>test@gmail.com</emailTo>
        <path>Server/.*/resources/schema/v.*/.*/.*-dbSchemaDescriptor\.xml,Server/.*/resources/SpringIOC/dataupgrader/v.*/.*/.*-dataUpgrader\.xml,Server/.*/java/com/hp/test/dataupgrader/v.*/.*/.*\.java,Server/.*/resources/indexes/v.*/.*\.index,Server/.*/resources/SpringIOC/vanilla/.*\.xml</path>
    </rule>
    <rule>
        <name>test_12.55.6</name>
        <repo>test</repo>
        <branch>refs/heads/12.55.6</branch>
        <emailTo>test@gmail.com</emailTo>
        <path>Server/.*/resources/schema/v.*/.*/.*-dbSchemaDescriptor\.xml,Server/.*/resources/SpringIOC/dataupgrader/v.*/.*/.*-dataUpgrader\.xml,Server/.*/java/com/hp/test/dataupgrader/v.*/.*/.*\.java,Server/.*/resources/indexes/v.*/.*\.index,Server/.*/resources/SpringIOC/vanilla/.*\.xml</path>
    </rule>
  </rules>
</configurations>

看了很多之后我发现没有人使用这个选项并且有一个很好的理由,我可以在创建之前删除我想要创建的子节点,如果它已经存在它会被删除,如果它不存在,它将什么都不做 - 所以我可以稍后创建它。

所以这是最终脚本:

    #!/bin/bash
    LOCK_BRANCH="66.66.66" 
    #Delete subnode $LOCK_BRANCH if already exist
    xmlstarlet ed -L -d  "/configurations/rules/rule[name='$LOCK_BRANCH']" config.xml
    #Adding a new subnode to certain nodes
    xmlstarlet ed -L --subnode  "/configurations/rules" --type elem -n rule config.xml

    #Adding text to the new node
    xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n name -v "$LOCK_BRANCH" config.xml
    xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n repo -v "mqm" config.xml
    xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n branch -v "refs/heads/12.55.99" config.xml
    xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n emailTo -v "imichael@gmail.com" config.xml
    xmlstarlet ed -L --subnode "/configurations/rules/rule[last()]" --type elem -n path -v "Server/.*/schema/v.*/.*/.*-dbSchemaDescriptor\.xml,Server/.*/resources/" config.xml