[SOLVED] How do I parse certain tags from an XML file and store them in an array using Bash?

Issue

I am trying to parse an XML file and keep track of certain elements to store them in an array.

An example XML file trouble.xml looks something like this:

<trouble>
<problem>
<factor name = abc/>
</problem>
<problem>
<factor name = def/>
</problem>
<trouble>

These and repeat multiple times throughout trouble.xml.

I was able to use this:

echo 'cat //factor/@name' | xmllint --shell $filename | sed -n 's: name=\"\(.*\)\":\1:p' 

Output looks like this:

abc
def

This code snippet successfully prints the "names" of the factor tag. My problem now is finding a way to somehow iterate through that list of names and save them into an array?

Solution

With mapfile, you don’t need to loop through the results

#!/usr/bin/env bash

# Read the array from the output of processing xml
mapfile -t array < <(
  xmllint --shell <<<'cat //factor/@name' a.xml |
    sed -n 's: name=\"\(.*\)\":\1:p'
)

# Debug print the array declaration
typeset -p array

Actual output from test data:

declare -a array=([0]="abc" [1]="def")

In case your bash is too old to provide a mapfile. Here is an alternative method:

#!/usr/bin/env bash

# Read the array from the output of processing xml
IFS=$'\n' read -r -d '' -a array < <(
  xmllint --shell <<<'cat //factor/@name' a.xml |
    sed -n 's: name=\"\(.*\)\":\1:p'
)

Answered By – Léa Gris

Answer Checked By – Pedro (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.