linux 在现有的相同元素后面添加新元素

laawzig2  于 2023-02-03  发布在  Linux
关注(0)|答案(2)|浏览(155)

我正在尝试修改Apache Tomcatserver.xml文件。我想在最后一个Connector定义之后添加一个新元素,但我的解决方案将新内容添加到Service的末尾,而不是最后一个Connector之后。

    • 这是我的XML:**

(我从真正的XML中删除了不相关的属性和元素,使其更具可读性)

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
    <Listener className="org.aaa"/>
    <Listener className="org.bbb" SSLEngine="on"/>
    <GlobalNamingResources>
        <Resource name="UserDatabase" auth="Container"/>
    </GlobalNamingResources>
    <Service name="Catalina">

        <Connector port="8080" protocol="HTTP/1.1"/> 
        <!-- INSERT A NEW CONNECTOR HERE -->

        <Engine name="Catalina" defaultHost="localhost">
            <Realm className="aa">...</Realm>
        </Engine>
    </Service>
</Server>

我的xmlstarlet代码插入了所需的内容,但是新的Connector元素的位置是错误的。

    • xml小明星:**
xmlstarlet edit \
    -s "//Server/Service[last()]" -t elem -n "Connector" \
    -s "//Server/Service[last()]/Connector" -t attr -n port -v "443" \
    -s "//Server/Service/Connector[@port='443']" -t attr -n protocol -v "org.apache.coyote.http11.Http11NioProtocol" \
    1.xml
    • 结果:**
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.aaa"/>
  <Listener className="org.bbb" SSLEngine="on"/>
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"/>
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1" port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"/>
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="aa">...</Realm>
    </Engine>

    <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"/>

  </Service>
</Server>

但我希望在现有的Connector之后有新的Connector

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.aaa"/>
  <Listener className="org.bbb" SSLEngine="on"/>
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"/>
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1" port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"/>

    <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"/>

    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="aa">...</Realm>
    </Engine>
  </Service>
</Server>

我在代码中遗漏了什么?

des4xlb0

des4xlb01#

试试看:

xmlstarlet edit\
--append  /Server/Service/Connector    --type elem -n "Connector" \
--insert '/Server/Service//Connector[last()]' -t attr -n "port" -v "443" \
--insert '/Server/Service//Connector[last()]' -t attr -n "protocol" -v "org.apache.coyote.http11.Http11NioProtocol" \
1.xml
xuo3flqw

xuo3flqw2#

使用xmlstarlet edit选项时,-s会将节点添加到其XPath参数的每个成员中,作为最后一个子代,-i作为前一个同级,-a作为后一个同级。使用-t attr时,它们都会添加一个属性,但对属性顺序没有影响。

xmlstarlet edit \
  -a '/Server/Service[@name="Catalina"]/Connector[last()]' -t elem -n 'Connector' \
  --var T '$prev' \
  -s '$T' -t attr -n port -v '443' \
  -s '$T' -t attr -n protocol -v 'org.apache.coyote.http11.Http11NioProtocol' \
file.xml

--var定义命名变量,反向引用$prev变量(又名$xstar:prev)引用由最近的-s-i-a选项创建的节点,这些选项都定义或重新定义了该变量(有关--var$prev的示例,请参见xmlstarlet.txt)。

相关问题