我有一个名为 Det.xml 的 xml,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns4:grtHgetRed xmlns:ns2="http://object" xmlns:ns3="http://object" xmlns:ns4="http://object">
<RequestId>lol</RequestId>
<MessageDateTime>54.009</MessageDateTime>
<SenderId>UH</SenderId>
<ReceiverId>GER</ReceiverId>
<TrackingNumber>45</TrackingNumber>
<ServerName>trewds</ServerName>
<ResponseType>success</ResponseType>
<StatusInfo>
<Status>success</Status>
<SystemMessage>Hagert</SystemMessage>
<UserMessage>Hgert</UserMessage>
<Origination>htref</Origination>
</StatusInfo>
</ns4:grtHgetRed>
</S:Body>
</S:Envelope>
我试图在 Unix shell 脚本中使用它来获取ResponseType
节点值,所以我尝试了以下操作:success
xmllint
echo "cat //*[local-name()='S:Envelope'/*[local-name()='S:Body']/*[local-name()='ns4:grtHgetRed']/*[local-name()='ResponseType']" | xmllint --shell Det
.xml | sed '/^\/ >/d' | sed 's/<[^>]*.//g'
但这不起作用。我xpath
的unix环境中也没有。谁能告诉我我在这里做错了什么?
我也尝试使用statusMSG=="$(echo "cat /Envelope/Body/grtHgetRed/ResponseType/text()" | xmllint --nocdata --shell response.xml | sed '1d;$d')"
, then echo "$statusMSG"
,但这给出了空回声。这是因为命名空间问题吗?
答案1
如果你的Det.xml
总是这样(例如不会有任何额外的ResponseType
节点),你可以简单地使用这个:
xmllint --xpath 'string(//ResponseType)' Det.xml
它会吐出:success
如果您的 xmllint 由于某种原因没有 xpath,那么您始终可以使用正则表达式来处理此类事情:
grep -Po '(?<=<ResponseType>)\w+(?=</ResponseType>)' Det.xml
它使用 Perl 正则表达式来允许正向前视/后视,并且仅显示匹配的部分(而不是整行)。这将输出与上面相同的结果,而根本不使用 xmllint / xpath。
答案2
当您寻找xmllint
不使用--xmlpath
选项的解决方案时,以下方法对我有用:
echo "cat //ResponseType/text()" | xmllint --nocdata --shell /tmp/Det.xml | grep -v '/'
success
您的示例statusMSG=="$(echo "cat /Envelope/Body/grtHgetRed/ResponseType/text()" | xmllint --nocdata --shell response.xml | sed '1d;$d')"
不起作用,因为您使用了echo "cat .../text()"
内部引号而没有引用,并且使用了 == 运算符而不是赋值。