xml - 如何在 Linux shell 脚本中仅提取 xml 树响应中的顶级元素?
问题描述
下面是显示名称列表和 manager_add 的 shell 脚本
name=($(grep -oP '(?<=name>)[^<]+' <<< "$vsppProxy_res"))
for i in ${!name[*]}
do
echo "$i" "${name[$i]}"
done
managers=($(grep -oP '(?<=manager_addr>)[^<]+' <<< "$vsppProxy_res"))
for i in ${!managers[*]}
do
echo "$i" "${managers[$i]}"
done
到目前为止的输出是:
0 名称0 1 名称1 2 名称2 3 名称3 .................................... ……………………………………………………………………………………………………………………………………………………………… .... 0 manager_add0 1 manager_add1 2 manager_add2 ................................... ...........
xml 响应包含 3 个顶级元素,例如,
<elem id="0">
每个顶级元素都包含子元素,例如<elem id="0"
>,具体取决于大小。但是,要求只需要提取顶级元素<elem id="0">
示例 xml 如下所示:
<X>
<regs>
<elem id="0">
<id>1</id>
<name>name0</name>
<warn>1</warn>
<manager_addr>manager_addr0</manager_addr>
<warn_desc>
<size>14</size>
<elem id="0">
<sev>2</sev>
<description>description</description>
<warning_id>1</warning_id>
<deployment_id>1</deployment_id>
<context_id>00</context_id>
<num_of_occurrences>1</num_of_occurrences>
<deployment_name>prod1</deployment_name>
</elem>
<elem id="1">
<sev>2</sev>
<description>description</description>
<warning_id>1</warning_id>
<deployment_id>1</deployment_id>
<context_id>00</context_id>
<num_of_occurrences>1</num_of_occurrences>
<deployment_name>prod1</deployment_name>
</elem>
</warn_desc>
</elem>
<elem id="1">
<id>2</id>
<name>name1</name>
<warn>1</warn>
<manager_addr>manager_addr1</manager_addr>
<warn_desc>
<size>1</size>
<elem id="0">
<sev>3</sev>
<description>description</description>
<warning_id>2</warning_id>
<context_id>00</context_id>
<num_of_occurrences>1</num_of_occurrences>
</elem>
</warn_desc>
</elem>
</regs>
</X>
预期的输出应该是:
经理:name0 manager_add0 ................................................... ……………………………………………………………………………………………………
请提供您的建议。谢谢你。
解决方案
尝试使用正则表达式解析 XML 是个坏主意。您应该使用支持 XML 的工具。转换 XML 文档的一个明显选择是XSLT。
考虑以下 shell 脚本,它将 XSLT 样式表应用于在命令行中传递给它的文件:
#!/bin/sh
# Use a temporary file for the XSLT stylesheet
stylesheet=$(mktemp)
cat >"$stylesheet" <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" encoding="UTF-8" />
<xsl:variable name="newline"><xsl:text>
</xsl:text></xsl:variable>
<xsl:template match="/X">
<xsl:for-each select="regs/elem">
<xsl:value-of
select="concat('Manager: ', name, ' ', manager_addr, $newline)" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
EOF
# Adjust as needed for whichever xslt processor you want to use
xsltproc "$stylesheet" "$1"
# xalan -xsl "$stylesheet" -in "$1"
# xmlstarlet tr "$stylesheet" "$1"
rm -f "$stylesheet"
用法:
$ ./transform.sh input.xml
Manager: name0 manager_addr0
Manager: name1 manager_addr1
推荐阅读
- python - python中的json值
- python - 在 Python 中展平嵌套列表
- api - PowerBI Report Server (on prem) - 保护 CacheRefreshPlan API
- css - 如何将画布和列表放在同一个div中
- asp.net - 我无法使用 Google Search Console 或 PageSpeedInsights 加载或抓取我的网站
- python-3.x - 我有与 Luhn_Algorithim 相关的信用卡验证查询:在 python 中
- elasticsearch - 如何在 Kibana 中搜索带有特殊字符的单词 - Elasticsearch
- android - 如何在两个 ConstraintSet 之间进行延迟?
- html - 悬停在子 div 上在父 div 上添加阴影
- ios - Firebase.configure() 停止 AppDelegate:OpenUrl() 被调用