You are not logged in.

#1 2017-07-10 19:58:46

darthearon
Member
Registered: 2014-04-01
Posts: 24

[Solved] Editing XML with sed or xmlstarlet

I am looking for a way to insert data into the comment field of specific <check_id>'s. In theory i would like to make a text file with a series of lines similar to "check_id_XXX=respective_comment".  Then i would run some command against that text file and it would insert comments were they go. I have searched carious forums, but all examples i have found show people changing comments in files like this "<check_id1><comments>example</comments><\check_id1>" and those examples do not help in my situation.

EXAMPLE FILE
=========

<check>
...
<check_id>1</check_id>
...
<comment></comment>
...
</check>



<check>
...
<check_id>2</check_id>
...
<comment></comment>
...
</check>




<check>
...
<check_id>3</check_id>
...
<comment></comment>
...
</check>
........

Last edited by darthearon (2017-07-12 13:32:39)


Cya At The Table

Offline

#2 2017-07-10 20:16:00

progandy
Member
Registered: 2012-05-17
Posts: 5,190

Re: [Solved] Editing XML with sed or xmlstarlet

xmlstarlet uses xpath, so you can leverage its abilities. There is even an example for child predicates in the documentation here:
https://www.w3schools.com/xml/xpath_syntax.asp

xmlstarlet ed --inplace -u "//check[check_id=2]/comment" -v Selected /tmp/test.xml

| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |

Offline

#3 2017-07-11 15:25:54

darthearon
Member
Registered: 2014-04-01
Posts: 24

Re: [Solved] Editing XML with sed or xmlstarlet

Firstly,
    thank you progandy.

Secondly,
    This seems to work to an extent, here are my results.

xmlstarlet ed --inplace -u "//check[check_id=2]/comment" -v Selected /tmp/test.xml

EXAMPLE OUTPUT
=========

<check>
...
<check_id>1</check_id>
...
<comment/>
...
</check>


<check>
...
<check_id>2</check_id>
...
<comment>Selected</comment>
...
</check>



<check>
...
<check_id>3</check_id>
...
<comment/>
...
</check>

======
EOF
======

This wipes the part of the comment fields. i need to have those left alone....i could run "sed 's/<comment\\>/<comment><comment\\>/' " but this feels like the wrong way to do things. arch motto being KISS. Keep It Simple Stupid. im going to keep working with this to see if i can come up with the expected result and post here if i find anything else.

Last edited by darthearon (2017-07-11 16:21:55)


Cya At The Table

Offline

#4 2017-07-11 15:52:37

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,523
Website

Re: [Solved] Editing XML with sed or xmlstarlet

How set are you on the format of that input text file?  If it could be as a php array, php could do this quite easily (sed could also readily convert your text file format to a php array).  Below two array values are set the script, but these could be included from a separate file:

#!/usr/bin/php
<?php

$check_id[1] = "first comment";
$check_id[2] = "second comment";

$xml = simplexml_load_string('<xml>' . file_get_contents('example.xml') . '</xml>');
foreach ($xml->check as $check) {
	if (isset($check_id[(int)$check->check_id]))
		$check->comment = $check_id[(int)$check->check_id];
	echo $check->asXML(), PHP_EOL;
}

Also if it were me and it could be changed, I'd definitely change the name "check_id" in the input comment list to something else as it is easy to confuse with the check_id element.  I'd probably call the array values $comment[1] and $comment[2] or something similar.

Also see how I used a [ code ] block in this post.  Please use these for code or file contents in your posts.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Online

#5 2017-07-11 16:05:07

darthearon
Member
Registered: 2014-04-01
Posts: 24

Re: [Solved] Editing XML with sed or xmlstarlet

For times sake, i decided to just work with sed and i was able get the desired result.  I can make all the edits i need with your command, then using the command below, restored the comments sections. Ill be using both commands in a bash file for automation.

SED COMMAND
======
"sed 's#<comment/>#<comment></comment>#" 

====
EOF
====



EXAMPLE BASH
============
xmlstarlet ed --inplace -u "//check[check_id=1]/comment" -v This /tmp/test.xml
xmlstarlet ed --inplace -u "//check[check_id=2]/comment" -v Is /tmp/test.xml
xmlstarlet ed --inplace -u "//check[check_id=3]/comment" -v A /tmp/test.xml
xmlstarlet ed --inplace -u "//check[check_id=4]/comment" -v Test /tmp/test.xml
sed -i 's#<comment/>#<comment></comment>#' /tmp/test.xml
cat /tmp/test.xml

====
EOF
====





EXAMPLE OUTPUT
=========

<check>
...
<check_id>1</check_id>
...
<comment>This</comment>
...
</check>

<check>
...
<check_id>2</check_id>
...
<comment>Is</comment>
...
</check>


<check>
...
<check_id>3</check_id>
...
<comment>A</comment>
...
</check>
<check>
...
<check_id>4</check_id>
...
<comment>Test</comment>
...
</check>
======
   EOF
======

Last edited by darthearon (2017-07-11 16:22:16)


Cya At The Table

Offline

#6 2017-07-11 16:14:18

darthearon
Member
Registered: 2014-04-01
Posts: 24

Re: [Solved] Editing XML with sed or xmlstarlet

Trilby,

    the actual XML document I'm working with is a checklist that feeds into another program that i never see and i don't know what kind of changes it can handle. i just need a way to easily insert a predefined comments into predefined check numbers that i will answer the same on every new checklist, saving me time copying and pasting the same two hundred (half of the time its more than that) checks over and over again. The actual attributes that are in the file are very different from what i have shown here. I was just trying to make the problem easier to understand.


Cya At The Table

Offline

#7 2017-07-11 16:19:42

darthearon
Member
Registered: 2014-04-01
Posts: 24

Re: [Solved] Editing XML with sed or xmlstarlet

Also, i am not allowed to use php in my environment, but i do appreciate the offer. thanks for the tip about code blocking. I was wondering how that was done, just figured it out...i don't post often enough.


Cya At The Table

Offline

#8 2017-07-11 16:19:45

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,523
Website

Re: [Solved] Editing XML with sed or xmlstarlet

The format of the xml can be any valid xml - I was commenting on the format of your list of comments which you've only specified as "similar to check_id_XXX=respective_comment".

And again, use code tags. (edit: this was cross posted with the above - but another lesson here, you can edit posts rather than making multiple posts in sequence).


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Online

#9 2017-07-11 16:37:26

darthearon
Member
Registered: 2014-04-01
Posts: 24

Re: [Solved] Editing XML with sed or xmlstarlet

Sorry, i hadn't seen your post about code tags until after I had already posted another message, my previous posts have been edited. Can this be marked as solved? I can not be more specific as to the actual format of the XML file, it cannot be shared outside the facility.

Last edited by darthearon (2017-07-11 16:38:01)


Cya At The Table

Offline

#10 2017-07-12 02:18:07

JohnBobSmith
Member
From: Canada
Registered: 2014-11-29
Posts: 804

Re: [Solved] Editing XML with sed or xmlstarlet

Edit your first post and add [SOLVED] to the title.


I am diagnosed with bipolar disorder. As it turns out, what I thought was my greatest weakness is now my greatest strength.

Everyday, I make a conscious choice to overcome my challenges and my problems. It's not easy, but its better than the alternative...

Offline

#11 2017-07-12 14:04:43

progandy
Member
Registered: 2012-05-17
Posts: 5,190

Re: [Solved] Editing XML with sed or xmlstarlet

Great that it works for you. If you want end tags, then you can try to run canonicalization (c14n) instead of the sed command. The format with end tag should be the canonical form.

xmlstarlet c14n /tmp/test.xml

Edit: This option doesn't have inplace editing, so you'd have to write to a temporary file and then replace the original with a move.

Last edited by progandy (2017-07-12 14:07:55)


| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |

Offline

#12 2017-07-12 15:06:17

darthearon
Member
Registered: 2014-04-01
Posts: 24

Re: [Solved] Editing XML with sed or xmlstarlet

progandy,

Thank you for your assistance.  As i said earlier the actually document is different than what i posted. What actually wound up working was something like this...

xmlstarlet ed --inplace -u "//check[randomtag[check_id=\"v-2\"]]/comment"



<check>
    <randomtag>
         <check_id>v-1</check_id>
    </randomtag>
    <comment>This</comment>
...
<check>
    <randomtag>
         <check_id>v-2</check_id>
    </randomtag>
    <comment>This</comment>
...
<check>
    <randomtag>
         <check_id>v-3</check_id>
    </randomtag>
    <comment>This</comment>
...
<check>
    <randomtag>
         <check_id>v-4</check_id>
    </randomtag>
    <comment>This</comment>
...

it just took some trial and error. Than you very much for the c14n tip. very helpful.

Last edited by darthearon (2017-07-12 16:18:06)


Cya At The Table

Offline

Board footer

Powered by FluxBB