我目前正在与awk进行斗争,以从基于xml的文件中提取多个字符串,并以csv格式导出这些字符串
下面是我要获取的标签的片段:
<GroupInfo Description="" Name="Site 2" Path="My Company\Site 2"/>
...
...
<PrivateInsightServerList EnableEntireServerList="1" >
<PrivateInsightServer Address="douda" LegacyClientSupport="1" Port="80" Protocol="HTTP"/>
</PrivateInsightServerList>
<PrivateInsightServerList EnableEntireServerList="1" >
<PrivateInsightServer Address="douda2" LegacyClientSupport="0" Port="443" Protocol="HTTPS"/>
</PrivateInsightServerList>
我不知道该如何解析文件,因为xml中的服务器数量可能在0到N之间变化,但是总是具有相同的结构。
理想情况下,我正在csv中寻找以下内容,并将N个服务器从同一xml文件添加到同一行,如下所示:
path,address,port,protocol
例如来自摘要:
My company\site 2,douda,80,HTTP,douda2,443,HTTPS
答案 0 :(得分:0)
由于它是必需的,而您尚未提供,因此我假设您的根XML元素只是“ <root>
”。
XML嵌套不好(我希望PrivateInsightServerList
是GroupInfo
的子代),我们将需要一些技巧。没关系。
首先,使用xmlstarlet
xml sel -t -m '/root/GroupInfo' --var groupinfo=@Path \
-m '/root/PrivateInsightServerList[@EnableEntireServerList=1]' \
-v '$groupinfo' -o "," \
-v PrivateInsightServer/@Address -o "," \
-v PrivateInsightServer/@Port -o "," \
-v PrivateInsightServer/@Protocol -nl \
input.xml
-m '/root/GroupInfo' --var groupinfo=@Path
它将Path属性存储在变量中以供以后使用-m '/root/PrivateInsightServerList[@EnableEntireServerList=1]'
限制EnableEntireServerList
不为1的情况下选择的节点-v ... -o ","
输出所需的值,然后输出换行符(-nl
)(您也可以使用“兄弟” XPath代替缓存Path
的变量,例如
-v //GroupInfo/@Path
,但可能无法可靠地运行,就像我说的那样,XML对我来说似乎并不“好”。
由于您还用awk
标记了该标签,因此我假设您最近使用了XML模块gawk
和gawkextlib
(不是您不能在简直awk
,但是如果学习XML解析不是手头的任务,那将不是很有效。)
@load "xml"
XMLSTARTELEM &&
XMLPATH~/GroupInfo$/ { mypath=XMLATTR["Path"] }
XMLSTARTELEM &&
XMLPATH~/PrivateInsightServerList$/ { ok=XMLATTR["EnableEntireServerList"] }
XMLSTARTELEM &&
XMLPATH~/PrivateInsightServerList[/]PrivateInsightServer/ {
if(ok==1) printf("%s,%s,%s,%s\n",
mypath,XMLATTR["Address"],XMLATTR["Port"],XMLATTR["Protocol"])
}
这是一个有点原始的东西(我还没有使用DOM xmltree
模块),上面有三个块,每个块在XMLSTARTELEM
上触发并检查XMLPATH
包含完整的元素的XPath。前两个块缓存Path
和EnableEntireServerList
,最后一个块根据需要打印出CSV。
运行gawk -f parse.awk input.xml
(“最近”是指gawk-4.1或更高版本)
我希望这两种方法都会出现问题,具体取决于XML模式和数据顺序。