4

I have a datafile like this:

<Key name="com.ahsay.afc.cpf.UserGroup" content="" allowMultiple="Y"> <Value name="rsv-id" inheritParentAttribute="Y" type="string" data="1328200856753" /> <Value name="rsv-group-name" inheritParentAttribute="Y" type="string" data="group 1" /> <Value name="rsv-user-type" inheritParentAttribute="Y" type="string" data="backup-user" /> <Value name="rsv-owner" inheritParentAttribute="Y" type="string" data="" /> <Key name="com.ahsay.afc.cpf.User" content="" allowMultiple="Y"> <Value name="rsv-id" inheritParentAttribute="Y" type="string" data="13279083887401" /> <Value name="rsv-login-name" inheritParentAttribute="Y" type="string" data="name1" /> </Key> <Key name="com.ahsay.afc.cpf.User" content="" allowMultiple="Y"> <Value name="rsv-id" inheritParentAttribute="Y" type="string" data="13279083887401" /> <Value name="rsv-login-name" inheritParentAttribute="Y" type="string" data="name2" /> </Key> </Key> <Key name="com.ahsay.afc.cpf.UserGroup" content="" allowMultiple="Y"> <Value name="rsv-id" inheritParentAttribute="Y" type="string" data="1328200856753" /> <Value name="rsv-group-name" inheritParentAttribute="Y" type="string" data="group 2" /> <Value name="rsv-user-type" inheritParentAttribute="Y" type="string" data="backup-user" /> <Value name="rsv-owner" inheritParentAttribute="Y" type="string" data="" /> <Key name="com.ahsay.afc.cpf.User" content="" allowMultiple="Y"> <Value name="rsv-id" inheritParentAttribute="Y" type="string" data="13279083887401" /> <Value name="rsv-login-name" inheritParentAttribute="Y" type="string" data="name3" /> </Key> <Key name="com.ahsay.afc.cpf.User" content="" allowMultiple="Y"> <Value name="rsv-id" inheritParentAttribute="Y" type="string" data="13279083887401" /> <Value name="rsv-login-name" inheritParentAttribute="Y" type="string" data="name4" /> </Key> </Key> 

I know the login name of the record I want, and I need to match it to a group. Let's say I want to know what group name3 is (the answer is group 3). Currently I can get the name of the group out of the file with:

perl -ne 'print "$_\n" foreach /name="rsv-group-name".*\ data="([^"]*)"/g;' 

but I have no idea how to match it with a user. How can I do that in a script?

1
  • How is name3's membership of group 3 determined ? The text 'group 3' does not feature in the datafile.
    – steve
    CommentedMay 25, 2018 at 19:42

3 Answers 3

2

The group is group 2, not group 3:

xmlstarlet sel -t \ -v '//Key[Key/Value[@name="rsv-login-name" and @data="name3"]]/Value[@name="rsv-group-name"]/@data' -nl file.xml 

Or, with a query value taken from the command line:

xmlstarlet sel -t --var data="'name3'" \ -v '//Key[Key/Value[@name="rsv-login-name" and @data=$data]]/Value[@name="rsv-group-name"]/@data' -nl file.xml 

Alternatively,

xmlstarlet sel -t --var data="'name3'" \ -m '//Key/Key/Value[@name="rsv-login-name" and @data=$data]' \ -v '../../Value[@name="rsv-group-name"]/@data' -nl file.xml 

The output from either of these will be group 2.

The XPath query looks for a Key/Key/Value node that has name="rsv-login-name" and data="name3", and for the Key that this node is a Key/Value node of, it returns the data attribute for the Value node that has name="rsv-group-name".

The XML I've used here is a slightly modified document that adds a <root> tag at the start and a </root> end tag at the end, just to make it a well-formed XML document.

    1

    Look into usling xslt scripts to transform or parse your XML, xsltproc is the binary you are looking for and w3cschools have a good getting started guide.

      1

      awk solution.

      $ awk -F= '/name="rsv-group-name"/{g=$NF}/data="name4"/{print substr(g,2,length(g)-5)}' inputfile 

        You must log in to answer this question.

        Start asking to get answers

        Find the answer to your question by asking.

        Ask question

        Explore related questions

        See similar questions with these tags.