This is a matter of efficiency, not troubleshooting. I have the following code snippet:
xmlstarlet -q fo -R <<<"$xml_content" | \
xmlstarlet ed -d "$xml_data" | \
xmlstarlet ed -d "$xml_index" | \
xmlstarlet ed -d "$xml_nodes/objects" | \
xmlstarlet ed -s "$xml_nodes" -t elem -n subnode -v "Hello World" | \
xmlstarlet ed -i "($xml_nodes)[last()]" -t attr -n x -v "0" | \
xmlstarlet ed -i "($xml_nodes)[last()]" -t attr -n y -v "0" | \
xmlstarlet ed -i "($xml_nodes)[last()]" -t attr -n z -v "1" \
> "$output_file"
The variable $xml_contentcontains the xml content tree and the
nodes are analyzed from a 472.6 MB file using the command cat.
The variable $output_file, as its name indicates, contains the path to the output file.
- The rest of the variables simply contain the corresponding XPaths that I want to change.
According to this brief article that helped come up with this code, this means that:
This is a bit inefficient as the XML file is parsed and written twice.
( loop 1000 ).
, script, 4 7 .
, , , , - , , , /, .
, , , , , , xmlstarlet XML-.
UPDATE
@Cyrus :
xmlstarlets :
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"
data, , , :
...
<node>
<subnode>A</subnode>
<subnode>B</subnode>
<objects>1</objects>
<objects>2</objects>
<objects>3</objects>
...
</node>
...
(split) , :
...
<node>
<subnode>A</subnode>
<subnode>B</subnode>
<subnode x="0" y="0" z="1">Hello World</subnode>
</node>
...
, xmlstarlet attributes node, 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"
, :
...
<node>
<subnode>A</subnode>
<subnode x="0" y="0" z="1">B</subnode>
<subnode>Hello World</subnode>
</node>
...
xmlstarlets , , @Cyrus, - attributes, --subnode innerText - Hello World.
, , " "
, , xmlstarlet ed \. :
($xml_nodes)[last()] $xml_nodes[text() = 'Hello World']$prev ( $xstar:prev) -i, answer. []-r temp node attr
--subnode, attributes.
. XMLStarlet 1.6.1 OS X El Capitan v 10.11.3
BONUS
, 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
$list , attributes. --value loop. :
, - . node, xml txt, , . XPath , .
: . loop 26 --subnodes loop 3 4 attr --subnode. xmlstarlet attr , - . .