如何使用 xmllint 或 xmlstarlet 替换 XML 文件中的字段?
我有以下 xml 文件:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut="http://">
<soapenv:Header>
<aut:Session>
<aut:IPAddress>127.0.0.1</aut:IPAddress>
<aut:SessionToken>true</aut:SessionToken>
<aut:ApplicationToken>861</aut:ApplicationToken>
</aut:Session>
</soapenv:Header>
<soapenv:Body></soapenv:Body>
</soapenv:Envelope>
What is the best way to replacement
by
?
这是我正在尝试的:
xmllint --shell file.xml << EOF
cd //*[local-name() = "Header"]/*[local-name() = "Session"]/text()/*[local-name() = "SessionToken"]/text()
set failed
save
EOF
当我尝试将 true 替换为 false 时,由于名称空间而遇到问题。
兄弟, 京东
I have the following xml file:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut="http://">
<soapenv:Header>
<aut:Session>
<aut:IPAddress>127.0.0.1</aut:IPAddress>
<aut:SessionToken>true</aut:SessionToken>
<aut:ApplicationToken>861</aut:ApplicationToken>
</aut:Session>
</soapenv:Header>
<soapenv:Body></soapenv:Body>
</soapenv:Envelope>
What is the best way to replace <aut:SessionToken>true</aut:SessionToken>
by<aut:SessionToken>false</aut:SessionToken>
?
Here is what I'm trying:
xmllint --shell file.xml << EOF
cd //*[local-name() = "Header"]/*[local-name() = "Session"]/text()/*[local-name() = "SessionToken"]/text()
set failed
save
EOF
I'm having problems because of namespace when I try to replace true for false.
Br,
JD
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
处理 SOAP 信封时,我不会使用
*[local-name() = "..."]
它忽略名称空间。相反,请使用显式名称空间绑定。
要切换布尔值,例如
在
-N
之前添加-L
/--inplace
以就地编辑文件。读取其值:
When dealing with a SOAP envelope I wouldn't use
*[local-name() = "…"]
which ignores the namespace. Instead, use an explicit namespace binding.
To toggle the boolean, for example
Add
-L
/--inplace
before-N
to edit the file in-place.To read its value:
你快到了。那里只有一个额外的
text()
元素。在 xmlstartlet 中,尝试You're almost there. You just have an extra
text()
element in there. In xmlstartlet, try您使用
xmllint
的方法与正确的方法相距不远。只需添加命名空间处理并在 XPath 表达式中使用命名空间前缀。作为单行:
Your approach with
xmllint
is not far from correct. Just needs to add namespace handling and use namespace prefixes in XPath expression.As a one-liner:
操作方法:调试 XML 结构并替换节点的值
由于 Google 可能会引导其他人必须使用不同的结构和节点更改自己的 XML 文件,因此找到正确的语法来更改值可能会很困难。
Sidenode:尽管 xmlstarlet 可能是替换 XML 文件中的值的更好工具,大多数 Unices 都预装了 xmllint。
因此,以下实践展示了如何在交互模式(即调试)下使用 xmllint 浏览任何 xml 文件,以找到应替换的 Node(即语法) 。
现在,您可以通过 XML 树逐步走到所需的节点:
直接显示特定节点/路径的结构和值(无需事先
cd
):记住不要有尾部斜杠在路径末尾,因为它找不到节点:
假设我们想更改 IP 地址,最好先检查正确的路径:
或者只是获取节点的值:
首先保存原始文件作为
backup.xml
,然后应用更改file.xml
,保存并保留 xmllint:在交互模式下
help
将显示有关命令的更多详细信息。 xmllint#Shell 部分> 也可能是一个很好的资源。一旦确定了节点的正确路径(应该更改),您就可以参考更高效的 one-liner< /a> 正如 @LMC 所提到的,用于动态更改 XML 文件。
Howto: Debugging the XML structure and replacing values for a node
As Google might lead someone else here who has to alter his own XML file with a different structure and nodes, it could be arduous finding the proper syntax in order to change values.
Sidenode: eventough xmlstarlet might be the better tool for replacing values in XML files, most Unices have xmllint pre-installed.
Thus, the following practice shows how to navigate with xmllint in interactive mode (i. e. debug) through any xml file in order to find the Node (i.e syntax) which should be replaced.
Now you can walk step by step to the desired node through the XML tree :
Show directly the structure and values for a certain node/path (without prior
cd
):Bear in mind to not have a trailing slash at the end of the path as it won't find the node:
Assuming we would like to change the IP address, its a good idea to check first the proper path:
Or just get the value of the node:
Save first the original file as
backup.xml
, then apply changes tofile.xml
, save it and leave xmllint:In interactive mode
help
will show further details about commands. The section #Shell at xmllint might also be a good resource.As soon as the proper path for the node (which should be changed) has been identified, you can refer to the more efficient one-liner as mentioned by @LMC to change XML files on the fly.