4

Is there a command line command or utility I can use to show only the tag structure of an xml document? I looked at xmllint but I didn't see a switch to do it. For a structure like

<tag1><tag2><tag2-5>value1</tag2-5><tag3>value2</tag3></tag2></tag1>

I want to see

<tag1><tag2><tag2-5></tag2-5><tag3></tag3></tag2></tag1>
2
  • Is it always that trivial? Will you have attributes on the tags? Aug 22 '12 at 20:58
  • Yeah, it is always that trivial. I'm not worried about the properties. There is a lot of actual data that I don't need to see, I just need the tag names to build xpath expressions.
    – user394
    Aug 22 '12 at 21:27
2

I think (but am not at all sure) that you can get away with just stripping out the characters between > and < globally:

sed 's/>[^<]*</></g' /path/to/file.xml
2
  • This catches simple cases, but not <foo>hello↲world</foo> where is a newline. Nor CDATA (if you have this, you need a real HTML parser). Aug 23 '12 at 0:00
  • Crap :S The content data I want to filter out is a lot of text with newlines :(
    – user394
    Aug 23 '12 at 16:21
1

The following xmlstarlet command would set the values of each text-only node in your document to an empty string. It would additionally preserve whitespaces between nodes (not do pretty-printing) and omit adding an XML declaration tag (<?xml...?>):

xmlstarlet ed -P -O -u '//child::text()' -v '' file.xml

Given your example document in file.xml, this would produce

<tag1><tag2><tag2-5></tag2-5><tag3></tag3></tag2></tag1>

Without the -P and -O options:

<?xml version="1.0"?>
<tag1>
  <tag2>
    <tag2-5></tag2-5>
    <tag3></tag3>
  </tag2>
</tag1>

One could also use

xmlstarlet ed -d '//child::text()' file.xml

to delete the values rather than setting them to an empty string, but that would generate nodes with no value (rather than nodes with an empty value):

<?xml version="1.0"?>
<tag1>
  <tag2>
    <tag2-5/>
    <tag3/>
  </tag2>
</tag1>

Adding the -P and -O options would generate

<tag1><tag2><tag2-5/><tag3/></tag2></tag1>

Depending on what it is that you actually want to do, one could use the el (elements) sub-command of xmlstarlet to get another representation of the document structure:

xmlstarlet el file.xml

The output for your example:

tag1
tag1/tag2
tag1/tag2/tag2-5
tag1/tag2/tag3

See also xmlstarlet el --help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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