【问题标题】:Add parameter values to an existing tag in XML将参数值添加到 XML 中的现有标记
【发布时间】:2015-02-22 14:46:12
【问题描述】:

我正在尝试不同的方法来向我的 XML 文件中的现有标签添加新值。

我的原始 XML:

<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
      connectionTimeout="20000"
      redirectPort="8443"/>
  </Service>
</Server>

我希望它变成:

<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
      connectionTimeout="20000"
      redirectPort="8443"
      scheme="https"
      secure="true" SSLEnabled="true"
      keyAlias="tomcat" keyPass="welcome"
      keystoreFile="/data/matrix/automated-setup/openam.jks"
      keystorePass="welcome" clientAuth="false" sslProtocol="TLS"/>
  </Service>
</Server>

我不想在这里使用 XSLT。我怎样才能使用 sed 或 awk 做到这一点? 只能在标签下添加

【问题讨论】:

  • 在linux中使用xml解析器会增加命令开销。它必须是通用的命令集,例如 sed 或 awk。
  • 那么对于必须添加行的位置,Catalina 下或redirectPort 等之后,是否有任何一般规则?包括更多细节
  • 它只能添加到 标签下。在重定向后添加可以更好地查看添加了哪些额外的参数
  • 每个连接器选项卡是否总是以“redirectPort......”结尾?在此行之后您要添加额外的行吗?
  • 抱歉..我的意思是每个连接器端口选项卡都以“”结尾,在此行之前您要添加额外的行吗?

标签: xml shell awk sed


【解决方案1】:

这样的 sed 脚本可以工作

sed  '
/^[ ]*<Connector port=.*protocol=.*/,/[ ]*<\/Service>/ {
\#.*"/>$# {
s#\(.*"\)/>#\1\n      scheme="https"\n      keyAlias="tomcat" keyPass="welcome"\n      keystoreFile="/data/matrix/automated-setup/openam.jks"\n      keystorePass="welcome" clientAuth="false" sslProtocol="TLS"/>#g 
}
}' $1

在脚本后面加上文件名来调用脚本。

如果您想更改以下信息

  scheme="https"
  secure="true" SSLEnabled="true"
  keyAlias="tomcat" keyPass="welcome"
  keystoreFile="/data/matrix/automated-setup/openam.jks"
  keystorePass="welcome" clientAuth="false" sslProtocol="TLS"/>

对这部分脚本进行操作

\n      scheme="https"\n      keyAlias="tomcat" keyPass="welcome"\n      keystoreFile="/data/matrix/automated-setup/openam.jks"\n      keystorePass="welcome" clientAuth="false" sslProtocol="TLS"/>#g

此脚本给出的结果

<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
      connectionTimeout="20000"
      redirectPort="8443"
      scheme="https"
      keyAlias="tomcat" keyPass="welcome"
      keystoreFile="/data/matrix/automated-setup/openam.jks"
      keystorePass="welcome" clientAuth="false" sslProtocol="TLS"/>
  </Service>
</Server>

【讨论】:

  • 这对我不起作用。这里出了点问题。
  • 我稍微更改了命令以处理标签末尾的空间问题。它对我有用。
  • 当我尝试使用 apache tomcat 的原始文件,即 server.xml 时,它无法替换。
  • 您是否尝试过“sed -i.bak......”,它会备份带有 .bak 扩展名的文件并进行实际更改?
  • 是的。没有运气。如果您有 apace tomacat 设置,则在 conf 中有 server.xml 。该文件存在一些选项卡或空间问题,因此无法正常工作。
【解决方案2】:

如果你真的想用 sed 或 awk 来做,一种方法是

awk '{ print }
 /<Connector / {
   print "      scheme=\"https\""
   print "      secure=\"true\""
   print "      SSLEnabled=\"true\""
   print "      keyAlias=\"tomcat\" keyPass=\"welcome\""
   print "      keystoreFile=\"/data/matrix/automated-setup/openam.jks\""
   print "      keystorePass=\"welcome\" clientAuth=\"false\" sslProtocol=\"TLS\""
 }' foo.xml

这会将参数直接插入到包含&lt;Connector 的行下。 但是,这种方法很脆弱。例如,如果 XML 文件包含一行

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>

(也就是说,如果标签在同一行中关闭),那么它会产生意想不到的结果。有一些方法可以处理个别此类问题,但是在 sed 或 awk 中处理所有可能出错的情况将很困难,部分原因是您必须首先弄清楚所有情况是什么.想象一下,如果你不得不期待所有的一切,它会是什么样子

<Connector/>
<Connector />
<Connector><someothertag/></Connector>
<ConnectorProperties foo="bar"/>

...而且,老实说,你必须期待他们。我强烈建议您使用旨在处理 XML 而不是原始文本的工具。在我看来,用 sed 或 awk 修改 XML 文件是很鲁莽的。

【讨论】:

  • 是的,你是对的。我必须期待多个连接器标签,处理它们对我来说很乏味。我避免使用 XML 工具,因为如果脚本在客户环境中运行,它会增加为客户添加所需工具的开销。如果您知道在 CnetOS 类型的机器上默认可用的任何通用工具,请建议我。让我知道我是否能够处理多个
  • 我不使用 CentOS,所以我不知道他们的默认 repo 中有什么。检查他们是否有 xmlstarlet,然后您可以执行 xmlstarlet ed -a //Connector -t attr -n foo -v bar 将属性 foo="bar" 添加到 Connector 标记。您可以使用任何 XPath,而不是 //Connector
  • 按照当前的软件大小标准,XML 解析器的开销是微不足道的。唉,我们试图将小程序保持在 10K(而不是 10M)以下的日子已经一去不复返了。此外,您的客户不太可能已经有了可用的 XML 解析器。例如,Java 附带了一个 Xerces 版本,尽管上次我检查它是落后的并且有一些烦人的错误。
猜你喜欢
  • 1970-01-01
  • 2019-08-22
  • 1970-01-01
  • 2010-10-26
  • 2013-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
相关资源
最近更新 更多