Ava*_*lla 5 xml unix bash shell xmlstarlet
这是效率问题,而不是故障排除。我有以下代码片段:
# The -R flag restores malformed XML
xmlstarlet -q fo -R <<<"$xml_content" | \
# Delete xml_data
xmlstarlet ed -d "$xml_data" | \
# Delete index
xmlstarlet ed -d "$xml_index" | \
# Delete specific objects
xmlstarlet ed -d "$xml_nodes/objects" | \
# Append new node
xmlstarlet ed -s "$xml_nodes" -t elem -n subnode -v "Hello World" | \
# Add x attribute to node
xmlstarlet ed -i "($xml_nodes)[last()]" -t attr -n x -v "0" | \
# Add y attribute to node
xmlstarlet ed -i "($xml_nodes)[last()]" -t attr -n y -v "0" | \
# Add z attribute to node
xmlstarlet ed -i "($xml_nodes)[last()]" -t attr -n z -v "1" \
> "$output_file"
Run Code Online (Sandbox Code Playgroud)
该变量$xml_content包含
使用cat命令从大小为472.6 MB的文件中解析的内容和节点的xml树。
变量$output_file如其名称所示,包含输出文件的路径。
根据帮助编写此代码的这篇简短文章,它表明:
由于xml文件被解析并写入了两次,因此这有点效率低下。
就我而言,它被解析和写入两次以上(最终loop超过1000次)。
因此,以上面的脚本为例,该短片段的执行时间仅为4分7秒。
假设过多的,重复的,可能是效率低下的管道传输以及文件大小是代码运行缓慢的原因,那么我最终插入/删除的子节点越多,最终将使其执行得越慢。
如果要重申自己的观点或提出一个古老且可能已经回答的话题,我可能会单调,我事先表示歉意,但是,我真的很想了解xmlstarlet大型XML文档如何详细工作。
更新
正如@Cyrus在他先前的回答中所声称的:
这两个xmlstarlet应该可以完成工作:
Run Code Online (Sandbox Code Playgroud)xmlstarlet -q fo -R <<<"$xml_content" |\ xmlstarlet ed \ -d "$xml_data" \ -d "$xml_index" \ -d "$xml_nodes/objects" \ -s "$xml_nodes" -t elem -n subnode -v "Hello World" \ -i "($xml_nodes)[last()]" -t attr -n x -v "0" \ -i "($xml_nodes)[last()]" -t attr -n y -v "0" \ -i "($xml_nodes)[last()]" -t attr -n z -v "1" > "$output_file"
这产生了以下错误:
-:691.84: Attribute x redefined-:691.84: Attribute z redefined-:495981.9: xmlSAX2Characters: huge text node: out of memory-:495981.9: Extra content at the end of the document老实说,我不知道这些错误是如何产生的,因为我经常更改代码以测试各种情况和潜在的替代方法,但是,这就是我的窍门:
xmlstarlet ed --omit-decl -L \
-d "$xml_data" \
-d "$xml_index" \
-d "$xml_nodes/objects" \
-s "$xml_nodes" -t elem -n subnode -v "Hello World" \
"$temp_xml_file"
xmlstarlet ed --omit-decl -L \
-i "($xml_nodes)[last()]" -t attr -n x -v "0" \
-i "($xml_nodes)[last()]" -t attr -n y -v "0" \
-i "($xml_nodes)[last()]" -t attr -n z -v "1" \
"$temp_xml_file"
Run Code Online (Sandbox Code Playgroud)
关于实际data插入的内容,这是我开始时的内容:
...
<node>
<subnode>A</subnode>
<subnode>B</subnode>
<objects>1</objects>
<objects>2</objects>
<objects>3</objects>
...
</node>
...
Run Code Online (Sandbox Code Playgroud)
执行上面的(拆分)代码会给我我想要的东西:
...
<node>
<subnode>A</subnode>
<subnode>B</subnode>
<subnode x="0" y="0" z="1">Hello World</subnode>
</node>
...
Run Code Online (Sandbox Code Playgroud)
通过拆分它们,xmlstarlet可以将插入attributes到新创建的节点中,否则它将在创建之前将它们添加到last()所选Xpath 的实例中--subnode。从某种程度上来说,这仍然是低效的,但是代码现在不到一分钟就能运行。
以下代码,
xmlstarlet ed --omit-decl -L \
-d "$xml_data" \
-d "$xml_index" \
-d "$xml_nodes/objects" \
-s "$xml_nodes" -t elem -n subnode -v "Hello World" \
-i "($xml_nodes)[last()]" -t attr -n x -v "0" \
-i "($xml_nodes)[last()]" -t attr -n y -v "0" \
-i "($xml_nodes)[last()]" -t attr -n z -v "1" \
"$temp_xml_file"
Run Code Online (Sandbox Code Playgroud)
但是,给我这个:
...
<node>
<subnode>A</subnode>
<subnode x="0" y="0" z="1">B</subnode>
<subnode>Hello World</subnode>
</node>
...
Run Code Online (Sandbox Code Playgroud)
通过xmlstarlets将此帖子加入一个同样由@Cyrus回答的帖子中的内容,它会以某种方式首先添加attributes,然后创建is --subnode所在的innerText位置Hello World。
这是另一个引用,指出“ 每个编辑操作都按顺序执行 ”
上面的文章准确地解释了我要寻找的内容,但是我无法使其完全合用xmlstarlet ed \。另外,我尝试:
($xml_nodes)[last()]为$xml_nodes[text() = 'Hello World']$prev(或$xstar:prev)作为论点。[例子]-i-r重命名临时节点的后attr添加以上所有内容均插入,--subnode但不添加则保留新元素attributes。
注意:我在OS X El Capitan v 10.11.3上运行XMLStarlet 1.6.1
奖金
正如我在开始时提到的,我希望在loop这些方面使用点赞:
list="$(tr -d '\r' < $names)"
for name in $list; do
xmlstarlet ed --omit-decl -L \
-d "$xml_data" \
-d "$xml_index" \
-d "$xml_nodes/objects" \
-s "$xml_nodes" -t elem -n subnode -v "$name" \
-i "($xml_nodes)[last()]" -t attr -n x -v "0" \
-i "($xml_nodes)[last()]" -t attr -n y -v "0" \
-i "($xml_nodes)[last()]" -t attr -n z -v "1" \
"$temp_xml_file"
done
Run Code Online (Sandbox Code Playgroud)
在$list包含需要与各自的添加超过一千不同的名称attributes。所述--value各属性的可与每变化loop为好。鉴于以上模型:
loop如果将属性正确添加到相应的节点,那么最快和最准确的版本是什么?
在外部txt文件中创建节点列表,然后将这些xml元素(在txt文件内部)添加到 另一个XML文件中,会更快吗?如果是,怎么办?也许与sed或grep?
关于最后一个问题,我指的是像这样。必须xml从txt中添加txt 的节点必须是特定的,例如,至少可以由XPath选择,因为我只想编辑某些节点。
注意:以上模型仅是示例。实际loop将添加26 --subnodes每个loop和3或4个attr为每个--subnode。这就是为什么正确xmlstarlet添加attr而不是其他元素很重要的原因。必须按顺序添加它们。
小智 2
为什么不使用并行(或 SEM),以便可以在机器上可用的核心数量上并行执行作业?我使用的代码是解析一个包含 2 个变量的数组,我将其导出到本地只是为了确保进程是隔离的。
for array in "${listofarrays[@]}"; do
local var1;local var2
IFS=, read var1 var2 <<< $array
sem -j +0
<code goes here>
done
sem --wait
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
457 次 |
| 最近记录: |