XMLGREP(1)

NAME
xmlgrep - print XML elements matching a pattern

SYNOPSIS
xmlgrep [-CcEiLlPqv] [-I indent] pattern [file ...]

DESCRIPTION
xmlgrep reads an XML stream from the specified files, or the standard input if no files are specified, and prints elements matched by pattern (as described in xmltools(7)) to standard output.

  Options
The following options are available:

-C  Print context around matches. The context of a match is made of all its ancestor elements.

-c  Suppress normal output and print the count of files that matched instead.

-E  Do not expand built-in and internal entities, as defined by the inline doctype of the document. By default, internally defined entities are expanded, and xmlgrep will fail on undefined entities with an XML syntax error. When expansion is disabled, the entity and the character sequence it represents are considered distinct.

-I indent
    Set the basic indentation step to indent spaces. The default is two spaces. The following flags can be appended to the indent value:

    ‘a’ Print attribute key/value pairs on a lines by themselves.

    ‘t’ Use one horizontal tab as the indentation unit, rather than one space.

    If no value is specified, it is taken as 0, so that ‘a’ is equivalent to ‘0a’.

-i  Ignore case distinction when matching regular expressions. Equality operators are not affected by this flag.

-L  Suppress normal output and print the names of files that did not match instead.

-l  Suppress normal output and print the names of files that matched instead.

-P  Do not discard all-whitespace elements. Also disable automatic indentation of output.

    Be warned: specifying -P effectively adds elements to the abstract XML tree as seen by xmlgrep; thus, some patterns may behave differently: two elements separated only by white space are not adjacent when this flag is enabled.

-q  Suppress all output; errors are still printed.

-v  Suppress normal output; instead, print the complement of the matched set. The result is equivalent to printing the original XML document with all intervals matched by the pattern removed.

EXAMPLES
Find all elements named ‘foo’ or ‘bar’:
    $ xmlgrep 'foo|bar'

Extract all elements ‘foo’ with ‘id’ attribute ‘bar’ and their subtrees:
    $ xmlgrep 'foo and @id=bar'

Find all elements that have an ‘a’ and a ‘b’ attributes (in any order):
    $ xmlgrep '@a and @b'

Trim elements with attributes ‘foo’ or ‘bar’:
    $ xmlgrep -v '@foo|@bar'

  Property lists
One of the original goals of xmlgrep (and the whole xmltools(7) package) was to ease command-line manipulation of property lists. Here are some sample applications.

Print key/value pairs whose key matches the regex ‘a*b’:
    $ xmlgrep '{(key/text()~"a*b")%*}'

Print keys associated with the string ‘k’:
    $ xmlgrep '*[key%string/text()=k]'

Print the key/value pairs whose value is a string:
    $ xmlgrep '{key%string}'

  HTML
Processing HTML is possible, though, most of the time, it must first go through tidy(1) (or some similar tool) in order to get valid XML. The following command should do the trick:
    $ tidy -q -asxml --numeric-entities yes

Then, to get a list of all anchors with a ‘href’ attribute:
    $ xmlgrep 'a and @href'

  Idioms
Even though xmlgrep works on XML intervals, it is possible to print an element without its subtree by chaining two instances of the program:
    $ xmlgrep -C 'x' | xmlgrep -v 'x/*'
Notice that -C here is needed because the output XML would not be well-formed otherwise. Adding an artificial root element is another common solution:
    $ { echo '<:>'; xmlgrep 'x'; echo '</:>'; } | \
    xmlgrep -v 'x/*' | xmlgrep '/:/*'

Extracting individual attributes is also possible with the help of some general text processing tools such as awk(1) or sed(1):
    $ xmlgrep -I a 'a and @href' | sed -n -n s/^href='\\(.*\\)'$/\1/p

  Special uses
You can abuse xmlgrep into performing some tasks it was not specifically designed for.

Reindent an XML file:
    $ xmlgrep '*'

Strip all XML tags:
    $ xmlgrep -P 'text()'

This last trick can be combined with normal uses of xmlgrep to produce plain text output. For example, to print all key/value pairs of a property list as plain text:
    $ xmlgrep -C -I 0 '{key%string}' | xmlgrep -P 'text()'

DIAGNOSTICS
The xmlgrep utility exits with 0 if a match was found, 1 if no match was found, >1 if an error occurred.

SEE ALSO
tidy(1), regex(3), xmltools(7)

AUTHORS
Nhat Minh Lê <minh@NetBSD.org>

BUGS
CDATA blocks containing ampersand characters get corrupted when the -E flag is in effect. This is due to the hackish way in which xmlgrep handles entities. Expat provides very little control over entity parsing, so these kind of tricks need to be done behind its back, which does not always produce good results.