1

我有以下xml。我想遍历每个节点并推送<url>

如果 == 1,则将值放入 bash 数组<extern>中。知道我应该如何处理这个问题吗?

<GraphXML>
      <graph isDirected="true">
        <node name="0">
          <label>font</label>
          <url>http://fonts.googleapis.com/css?</url>
          <data>
            <checktime>0.262211</checktime>
            <extern>1</extern>
          </data>
        </node>
        <node name="1">
          <label>logo</label>
          <url>http://example.com/example.png</url>
          <data>
            <dlsize>7545</dlsize>
            <checktime>0.280600</checktime>
            <extern>0</extern>
          </data>
        </node>
     </graph>
    </GraphXML>
4

2 回答 2

2

使用 xmllint:

out=$(echo "cat /GraphXML/graph/node/url|/GraphXML/graph/node/data/extern" | \
        xmllint --shell input | sed 's/<[^>]*>//g;s/[-][-]*//g;s/\/[^>]*>//')
set $out
i=0
while [ $#  -gt 0 ] ; do
  url=$1
  shift
  extern=$1
  shift
  if [ $extern -eq 1 ]; then
    array[$i]=$url
    let i++
  fi  
done

echo ${array[*]}
于 2012-12-21T04:56:53.230 回答
1

使用 bash

#!/bin/bash
declare -a ARR
while read -r line; do
    if [[ "$line" =~ ^\<(url|extern)\>(.*)\</[^\>]*\>$ ]]; then
        if [ "${BASH_REMATCH[1]}" == "extern" ]; then
            (( ${BASH_REMATCH[2]} == 0 )) && unset ARR[${#ARR[@]}-1]
        else
            ARR+=("${BASH_REMATCH[2]}")
        fi
    fi
done < <(grep -oE '<(url|extern)>.*</(url|extern)>' file.xml)

echo "${ARR[@]}"

解释

  • grep -oE- 使用扩展正则表达式-E匹配urlextern返回匹配-o
  • done < <(- 使用流程替换grep输入while循环。
  • while read -r line- 读取一行直到EOF退出while
  • ^\<(url|extern)\>(.*)\</[^\>]*\>$- 匹配行并保存到BASH_REMATCH数组中。
  • unset ARR[${#ARR[@]}-1]- 如果 extern 属性值为 0,则删除数组中的最后一个元素。
  • ARR+=(...)- 向数组添加新元素的简写形式。
于 2012-12-21T07:42:29.100 回答