Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want a simple little command to strip an XML-Header and Footer from a file:

<?xml version="1.0" encoding="UTF-8"?>
<conxml>
<MsgPain001>
    <HashValue>A9C72997C702A2F841B0EEEC3BD274DE1CB7BEA4B813E030D068CB853BCFECA6</HashValue>
    <HashAlgorithm>SHA256</HashAlgorithm>
    <Document>
                ...
    </Document>
    <Document>
                ...
    </Document>
</MsgPain001>
</conxml>

...

Should become just

<Document>
         ...
    </Document>
    <Document>
          ...
    </Document>

(note the indenting, the indent of the first document-tag should be stripped of.

This sounds like a (greedy) regex

<Document>.*</Document>

But I don't get it due to the linefeeds.

Could someone provide a simple sed script or similar to get it?

I need it in a pipe to compute a hash over the contained documents.

share|improve this question
add comment

2 Answers

up vote 5 down vote accepted

Using sed:

 sed -n '/<Document>/,/<\/Document>/ p' yourfile.xml

Explanation:

  • -n makes sed silent, meaning it does not output the whole file contents,
  • /pattern/ searches for lines including specified pattern,
  • a,b (the comma) tells sed to perform an action on the lines from a to b (where a and b get defined by matching the above patterns),
  • p stands for print and is the action performed on the lines that matched the above.

Edit: If you'd like to additionally strip the whitespace before <Document>, it can be done this way:

 sed -ne '/ <Document>/s/^ *//' -e '/<Document>/,/<\/Document>/ p' yourfile.xml
share|improve this answer
    
thanks, I'm sed noob. What about indenting whitespace? What does the ',' do ? –  Bastl Oct 20 '11 at 13:50
    
It works with whitespace as well as any other characters surrounding <Document>. See the update of my answer for deeper explanation. –  rozcietrzewiacz Oct 20 '11 at 13:59
    
good. that's nearly perfect. Now I need to strip off preceeding whitespace from the first line. Is it possible inside your command? –  Bastl Oct 20 '11 at 14:06
    
Yes, though it'll be a bit more complicated - see update. (At this point, I am not sure if it is the simplest way.) –  rozcietrzewiacz Oct 20 '11 at 14:36
1  
@Bastl Note that if there's any text between </Document> and the next <Document>, it'll be stripped. –  Gilles Oct 20 '11 at 17:29
add comment

To prevent text from being stripped between </Document> and the next <Document> you may have to use a series of sed commands (cf. Gilles' comment above).

Essentially sed reads the entire file into the hold buffer (so that the file contents can be treated as a single line) and marks the first and last Document tags for further processing.

# version 1
# marker: HERE
cat file.xml | 
sed -n '1h;1!H;${;g;s/\(<Document>.*<\/Document>\)/HERE\1HERE/g;p;}' | 
sed -n -e '/HERE<Document>/,/<\/Document>HERE/ p' | 
sed -e 's/^ *HERE\(<Document>\)/\1/' -e 's/\(<\/Document>\)HERE *$/\1/'

# version 2    (using the Bash shell)
# marker: $'\001'
cat file.xml | 
sed -n $'1h;1!H;${;g;s/\\(<Document>.*<\\/Document>\\)/\001\\1\001/g;p;}' | 
sed -n -e $'/\001<Document>/,/<\\/Document>\001/ p' | 
sed -e $'s/^ *\001//' -e $'s/\001 *$//' | 
cat -vet

... but I guess all this could be done more elegantly (& reliably) using xmlstarlet!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.