0

I need to get an attribute from an xml file in a bash script but I can't use neither xmllint --xpath neither xmlstarlet cause they are not available on the server where I work.

I've tried solution with grep, cut and sed but it's not a good solution in a long time.

There is grep_xml available on the machine, I can acces elements with it but when I'm trying to access my attribute I get "error unrecognized expression in handler"

this is my xml file

<?xml version="1.0" standalone="yes"?>
<p4codeline xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="p4codeline_1_1.xsd">
  <module name="kpreader" currentVersion="kpreader_1.1STD0" previousVersion="kpreader_1.0STD0">
    <codeline owner="undefined" path="//HEP/jcas/kpreader/trunk/...">
      <namingConvention/>
      <description>Main codeline for development</description>
      <rules>
        <rule>Develop on MAIN, and create a TAG codeline on release</rule>
        <rule>Never broke the build on the MAIN</rule>
      </rules>
    </codeline>
    <externals>
      <external viewPath="J2ep_BuildTools/..." codeLine="//CT/JAVA/J2ep_BuildTools/Source/tags/J2EP_BUILDTOOLS_1.6STD0/..." depotPath="."/>
    </externals>
  </module>
</p4codeline>

and i would need to access to the path attribute in codeline only with a solution based on bash or command.

I've tried something like

xml_grep -t '/p4codeline/module/codeline/@path' file.xml

And it answear me

error: unrecognized expression in handler: '/p4codeline/module/codeline@path' at /usr/bin/xml_grep line 183
5
  • 3
    Yes, don't leave us in the dark. If you go to a doctor, don't just say "Ouch!". Be specific. Commented Jun 26, 2013 at 9:30
  • What is the input, what did you try so far, what did it print, and what did you expect it (or a solution) to print? We need more detail. Commented Jun 26, 2013 at 9:35
  • For this I would use Perl + your XML parser of choice. Commented Jun 26, 2013 at 9:40
  • this is the difficulty I have to make it without perl python ruby or other nice stuff Commented Jun 26, 2013 at 9:55
  • @Jens +1 for good analogy. Commented Jun 26, 2013 at 10:07

2 Answers 2

1

As these things usually go, this command is highly dependent on your input

$ awk '/path/ {print $4}' FS='"' file.xml
//HEP/jcas/kpreader/trunk/...
Sign up to request clarification or add additional context in comments.

Comments

0

You can basically use grep like xpath "sort of". For this scenario I would use

grep  -oP "(?<=[<]codeline)[^<]+" file.xml |  grep  -oP "(?<=path\=\")[^\"]*"

if you need to take into account an xpath like /p4codeline/module/codeline/@path. You will need to transform the file to one-line input and pipe to some grep statements

tr -d '\n' <  file.xml | grep -Eo '<p4codeline .+/p4codeline>' | grep -Eo '<module .+/module>' |  grep  -oP "(?<=[<]codeline)[^<]+" | grep  -oP "(?<=path\=\")[^\"]*"

Put it together in a little bash script

#!/usr/bin/env bash
if [ -p /dev/stdin ]
  then
    xmlinput=`cat | tr -d '\n'`
else 
 xmlinput=`tr -d '\n' < ${1}`
fi

if [[ ${2} == "" ]]
 then
   ajpath="${1}/EOP"
else
  ajpath="${2}/EOP"
fi

echo "${ajpath}" | tr '/' '\n' | while read i
 do
# if first letter is @ look for attribute
if [[ "$i" == "EOP" ]]
  then
   echo $xmlinput
   break
fi
if [[ "${i:0:1}" == "@" ]]
  then
   xmlinput=`echo $xmlinput | grep  -oP "(?<=${i#?}\=\")[^\"]*"`
  else
  if [[ "$i" != "" ]]
   then
   xmlinput=`echo $xmlinput | grep -Eo "<${i}.+/${i}>"`
  fi
fi
done

You execute the script like anjopath.sh file.xml /p4codeline/module/codeline/@path

will give you //HEP/jcas/kpreader/trunk/...

anjopath.sh file.xml /p4codeline/module/@name

will give you kpreader

anjopath.sh file.xml /p4codeline/module/codeline/rules

will give you

> <rules> <rule>Develop on MAIN, and create a TAG codeline on
> release</rule> <rule>Never broke the build on the MAIN</rule> </rules>

you can also pipe xmlinput like this

cat file.xml | anjopath.sh /p4codeline/module/codeline/rules

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.