Search code examples
xmlxpathxmlstarlet

xmlstarlet: How do I omit elements with a specific attribute?


I would like to retrieve certain XML elements but only if they do not contain a specific attribute with starlet.

Here is an XML example in file myFile.xml:

<?xml version="1.0"?>
<document>
        <classInfo>
                <subjects>
                        <subject id="1" type="someType">
                                <subjectname>Foo1</subjectname>
                        </subject>
                        <subject id="2" subtype="someSubtype" type="someType">
                                <subjectname>Foo2</subjectname>
                        </subject>
                </subjects>
        </classInfo>
</document>

Now, all elements without subtype shall be considered further while all elements with a subtype (any subtype) shall be ignored.

So far, there is only the xmlstarlet selection considering all elements:

xmlstarlet sel -T -t -m "//subject[@type='someType']" -v '@id' -o $'\t' -v 'subjectname[text()]' -nl myFile.xml

This results in

1 Foo1

2 Foo2

But the desired outcome is

1 Foo1

In which way has this selection to be enhanced to omit every subject with a subtype?


Solution

  • Try adding the predicate [not(@subtype)] to your match...

    -m "//subject[@type='someType'][not(@subtype)]"