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

时间:2017-12-07 09:01:49

标签: xml bash shell xmlstarlet

我有一个脚本,它将一个子节点添加到我的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>

1 个答案:

答案 0 :(得分:2)

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

所以这是最终的剧本:

    #!/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