-4

I'm needing to parse a particular set of XML files for a value.

In this instance, I need to find every access id for <group>THISGROUP</group> with <permission>WRITE</permission>

In the example below, I would need VX-3422867 returned. Also, I need to be able to accomplish this within a bash script.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccessControlListDocument>
    <access id="VX-3422867">
        <loc>http://localhost:8080/API/item/VX-410070/access/VX-3422867</loc>
        <grantor>admin</grantor>
        <recursive>true</recursive>
        <permission>WRITE</permission>
        <group>THISGROUP</group>
    </access>
        <access id="VX-3422866">
        <loc>http://localhost:8080/API/item/VX-410070/access/VX-3422866</loc>
        <grantor>admin</grantor>
        <recursive>true</recursive>
        <permission>NONE</permission>
        <operation>
            <shape>
                <tag>original</tag>
            </shape>
        </operation>
        <group>THISGROUP</group>
    </access>
    <access id="VX-3422865">
        <loc>http://localhost:8080/API/item/VX-410070/access/VX-3422865</loc>
        <grantor>admin</grantor>
        <recursive>true</recursive>
        <permission>WRITE</permission>
        <group>TWO</group>
    </access>
    <access id="VX-3422869">
        <loc>http://localhost:8080/API/item/VX-410070/access/VX-3422869</loc>
        <grantor>admin</grantor>
        <recursive>true</recursive>
        <permission>ALL</permission>
        <group>THREE</group>
    </access>
    <access id="VX-3422868">
        <loc>http://localhost:8080/API/item/VX-410070/access/VX-3422868</loc>
        <grantor>admin</grantor>
        <recursive>true</recursive>
        <permission>ALL</permission>
        <group>FOUR</group>
    </access>
    <access id="VX-975588">
        <loc>http://localhost:8080/API/item/VX-410070/access/VX-975588</loc>
        <recursive>true</recursive>
        <permission>OWNER</permission>
        <user>user-one</user>
    </access>
</AccessControlListDocument>
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
CEC
  • 7
  • 1
  • You have a lot of reading to do, methinks. You should start perhaps [here](http://stackoverflow.com/questions/4984689/bash-xhtml-parsing-using-xpath). – Shawn Mehan Sep 02 '15 at 01:07
  • 1
    BTW, "this is my input, please write a program for me that gives me the output I want" is a subcategory of "please do my work for me", which is not particularly welcome here -- hence the downvotes. Making an effort to at least show what you've tried or considered is helpful. – Charles Duffy Sep 02 '15 at 02:38
  • at least he gave input and output ;-/ Good luck to all. – shellter Sep 02 '15 at 02:52
  • My apologies for not explaining everything I had tried. I'm sure you understand being in a pinch and needing help. – CEC Sep 03 '15 at 13:56

3 Answers3

2

To print the IDs for all access entries with groups THISGROUP and permission WRITE:

xmlstarlet sel \
  -t -m '//access[group="THISGROUP"][permission="WRITE"]' \
  -v @id -n <in.xml
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
2

You can select the @id attributes of the access elements who's group element value is equal to 'THISGROUP' and permission element value is equal to 'WRITE' with the following XPath:

/AccessControlListDocument/access[group = 'THISGROUP' and permission='WRITE']/@id 

As for executing in a bash script, you could look at using xmlstarlet:

xmlstarlet sel -t -v "/AccessControlListDocument/access[group = 'THISGROUP' and permission='WRITE']/@id" myFile.xml

Or with a variety of other options (xmllint, saxon-lint, saxon, python, xidel) as suggested in answers to How to execute XPath one-liners from shell?

Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
  • Thank you, I'm used to using Xidel. Turns out I was close to the syntax I needed, but not quite there. – CEC Sep 03 '15 at 13:56
0

whith xpath:

If you wanna only de first id atribute:

   <xsl:value-of select="/AccessControlListDocument/access[child::group='THISGROUP' and child::permission='WRITE']/@id"/>

If you wanna every id atribute whit that condition:

<xsl:for-each select="/AccessControlListDocument/access[child::group='THISGROUP' and child::permission='WRITE']">
<xsl:value-of select="./@id"/>
</xsl:for-each>

This means get the "id" atribute from "access" node child from "AccessControlListDocument" parent, where "access" node have children nodes "group" with value 'THISGROUP' and node "permission" with value 'WRITE'.

Mauro
  • 93
  • 8
  • This is actually a very good approach, as people are more likely to have xsltproc than they are to have xmlstarlet or an xmllint recent enough to have `--xpath`. You should perhaps show how to run it from bash, though. – Charles Duffy Sep 02 '15 at 03:10
  • I'd also suggest describing it as "With XSLT" rather than "with XPath". – Charles Duffy Sep 02 '15 at 03:13