Xmllint: get one result per line

Hi,

I'm trying to get some values from an xmlfile and want be able to process them. I'm using xmllint(v20901 on debian jessie) and this program directly outputs all results concatenated right after each other. I did not find a solution in the man page to get a different format or some output separator.

Here's the data:

XML-INPUT

<benno>
  <configuredarchives>
    <containerarchive>
      <identifier>my.archiveserver.com</identifier>
      <conditions>
        <all/>
      </conditions>
      <directorywatcher directory="/srv/benno/inboxes/my.archiveserver.com" pattern=".*.eml">
        <mailfile>
          <senderheaders>
            <name>X-REAL-MAILFROM</name>
            <name>RECIPIENT-FROM</name>
            <name>From</name>
          </senderheaders>
          <recipientheaders>
            <name>X-REAL-RCPTTO</name>
            <name>RECIPIENT-TO</name>
            <name>BCC</name>
            <name>To</name>
            <name>Cc</name>
          </recipientheaders>
          <secretheaders>
            <name>RECIPIENT-TO</name>
            <name>RECIPIENT-FROM</name>
            <name>BCC</name>
            <name>X-REAL-MAILFROM</name>
            <name>X-REAL-RCPTTO</name>
          </secretheaders>
        </mailfile>
      </directorywatcher>
      <configuredcontainers>
        <simplecontainer>
          <identifier>Foo Inc.</identifier>
          <conditions>
            <or>
              <domain sender="true" recipient="true" from="true" to="true" cc="true">foobar.de</domain>
              <domain sender="true" recipient="true" from="true" to="true" cc="true">foo.de</domain>
            </or>
          </conditions>
          <luceneindex version="LUCENE_36">
            <directory>/srv/benno/archives/my.archiveserver.com/foobar/index</directory>
          </luceneindex>
          <monthlyfsbox>
            <fshexbennobox>
              <monthlyfsjournal/>
              <directory>/srv/benno/archives/my.archiveserver.com/foobar/repo</directory>
              <subdirs>3</subdirs>
              <dirlength>2</dirlength>
              <compression>gzip</compression>
            </fshexbennobox>
          </monthlyfsbox>
        </simplecontainer>
      </configuredcontainers>
      <configuredcontainers>
        <simplecontainer>
          <identifier>Bla Blub</identifier>
          <conditions>
            <or>
              <domain sender="true" recipient="true" from="true" to="true" cc="true">blablub.de</domain>
            </or>
          </conditions>
          <luceneindex version="LUCENE_36">
            <directory>/srv/benno/archives/my.archiveserver.com/blablub/index</directory>
          </luceneindex>
          <monthlyfsbox>
            <fshexbennobox>
              <monthlyfsjournal/>
              <directory>/srv/benno/archives/my.archiveserver.com/blablub/repo</directory>
              <subdirs>3</subdirs>
              <dirlength>2</dirlength>
              <compression>gzip</compression>
            </fshexbennobox>
          </monthlyfsbox>
        </simplecontainer>
      </configuredcontainers>
    </containerarchive>
  </configuredarchives>
  <bennoRest>
    <jettyConfig>/etc/benno/jetty.xml</jettyConfig>
    <sharedSecret>verysecret</sharedSecret>
    <indexCacheTTL>300000</indexCacheTTL>
  </bennoRest>
</benno>

The used command

 xmllint --xpath "//fshexbennobox/directory/text()" /etc/benno/benno.xml 

The result

/srv/benno/archives/my.archiveserver.com/foobar/repo/srv/benno/archives/my.archiveserver.com/blablub/repo

Wanted result

/srv/benno/archives/my.archiveserver.com/foobar/repo
/srv/benno/archives/my.archiveserver.com/blablub/repo

So since there is no separator-character at all, the solution is not usable.

I got a workaround, which is not that efficient, but well it works:

#!/bin/bash
data="$(cat /etc/benno/benno.xml)"
count=$(xmllint --xpath "count(//fshexbennobox/directory)" - <<<"$data")
for((i=1;$i<=$count;i++)) ; do
        xmllint --xpath "(//fshexbennobox/directory)[$i]/text()" - <<<"$data"
        echo ""
done

Maybe you have some further tip. I absolutely want to stay with xmllint.

Oi. We had a similar problem -

xmllint --shell /path/to/inputfile <<< `echo 'cat /config/*/@*'`  | egrep '(pattern1|pattern2)' > outfile 

The "/config" part has the commands you would manually enter.

Best I can do for you. Maybe someone else has a better solution....

1 Like

ok. Thanks. That's a bit shorter.

 xmllint --shell /etc/benno/benno.xml <<<'cat /*/*/*/*/*/*/fshexbennobox/directory/text()' \
    | grep -vE '^(/ > ?)?( +-+)?$'