具备条件:
我无法使用任何 XML 解析器工具,因为我没有权限,只读
我的 xmllint 版本不支持 xpath,我无法更新它,只读
我没有 xmlstarlet 并且无法安装它
我的选择几乎仅限于字符串处理。
用户将提供一个输入参数,它将是块的名称。
所以,
让我们假设
NAME=${USER_INPUT}
我们将使用$NAME
作为参数来搜索将要搜索的 xml 块。
如何在 xml 文件中转换这样的通用 xml 块,如下所示:
<block>
<name>Bob</name>
<address>USA</address>
<email>[email protected]</email>
<phone>1234567</phone>
</block>
<block>
<name>Peter</name>
<food>France</address>
<cell>[email protected]</cell>
<drinks>Coke</drinks>
<car>Honda</car>
<bike>Mountain bike</bike>
</block>
所以我想在这里实现的事情是获取满足我的搜索的 xml 块,
例如NAME=Bob
;
脚本的输出应采用属性文件格式
name=Bob
address=USA
[email protected]
phone=1234567
这里需要考虑的一件事是每个块的 xml 格式是不同的。每个 xml 块的节点都不相同。
答案1
Perl 有一个漂亮的“段落模式”( -00
),其中记录(“行”)由空行而不是单个字符分隔\n
。使用它,您可以非常轻松地提取相关记录。因此,首先确保每个 之前有一个空行<block>
,然后使用段落模式来查找您要搜索的内容:
$ sed 's/<block>/\n<block>/' file | perl -00ne 'if(/<name>\s*bob\s*<\/name>/i){print}'
<block>
<name>Bob</name>
<address>USA</address>
<email>[email protected]</email>
<phone>1234567</phone>
</block>
现在,将其包装在 shell 脚本中(此处使用 bash):
#!/bin/ksh
## Read the search strings
tag="$1"
value="$2"
target="file.xml" ## change this to whatever your xml file is called
## Search
sed 's/<.\?block>/\n/' "$target" |
perl -00ne "if(/<$tag>\s*$value\s*<\/$tag>/i){
## May as well do the formatting in Perl as well
s# *<([^/]+?)>#\1=#g;
s/<\/.+?>//g;
print
}"
然后,运行脚本,并提供标签名称和所需值作为输入:
$ a.sh "name" "bob"
name=Bob
address=USA
[email protected]
phone=1234567