1

我正在用一个奇怪的层次结构中的 bash 脚本解析数百个 pom,以将所有项目的概述提取到一个报告中(maven-info-projects:project-team 不能一次性完成的事情)。由于未公开的原因,我不想弄乱父 pom 或尝试配置 maven-info-projects 部分。

我正在使用XMLStarlet,因为它已安装,而xmllint未安装。

给定一个 pom.xml 提取,其中包含:

<developer>
   <id>devId</id>
   <name>Developer Name</name>
   <email>dev@nowhere.com</email>
   <roles>
      <role>Project manager</role>
      <role>Developer</role>
   </roles>
</developer>

如何通过一次调用XMLStarlet来提取所有开发人员信息,包括多个角色?

目前,我可以通过以下方式提取大部分信息:

# Developers
locate_section_values $pom_file_name "/x:project/x:developers/x:developer" \
    "concat( \
        x:id, '|', x:name, '|', x:email, '|', x:roles, '|', \
        x:organization, '|', x:organizationUrl, '|', x:timezone
     )"

在哪里

function locate_section_values(){
  local xml_file=$1
  local section=$2
  local value_table=$3

  OLD_IFS=$IFS
  IFS=$'\n'
  xml_values=()
  xml_values=(`xmlstarlet sel -B -N x="http://maven.apache.org/POM/4.0.0" -t -m "$section" -v "$value_table" -nl $xml_file`)
  IFS=$OLD_IFS
}

然后我拆分结果:

  for developer in ${xml_values[@]}; do
    IFS='|' 
    set $developer # split into $1, $2, etc using | as seperator
    #echo "id:${1}, name:${2}, roles:${4}"

    if [ -n "${1}" ]; then # id
      developer_id=${1}
      developer_ids+=( $developer_id )
    fi
    ...

问题是,具有多个角色的开发人员将他们的角色连接起来:

 Project managerDeveloper

有没有办法告诉对 xmlstarlet 的原始调用将多个角色组合成一个逗号分隔的列表?

4

2 回答 2

2

我认为以下内容大致提供了您想要的内容,但是您必须将界面更改为locate_section_values

xmlstarlet sel -T -B -N x="http://maven.apache.org/POM/4.0.0" \
   -t -m "/x:project/x:developers/x:developer" -v "x:id" -o "|" \
   -v "x:name" -o "|" -v "x:email" -o "|" \
   -m "x:roles/x:role" -v "." -o "," -b -o "|" \
   -v "x:organization" -o "|" -v "x:organizationUrl" -o "|" \
   -v "x:timezone" --nl 
  $pom_file_name

这会将角色生成为逗号终止的列表,因为它更容易编码。


locate_section_valueseval

function locate_section_values() {
    local xml_file=$1 # $local_project_dir/$fixed_name/pom.xml
    local section=$2 #/x:project/x:modules/x:module
    local value_table=("${@:3}")

    OLD_IFS=$IFS
    IFS=$'\n'
    xml_values=($(xmlstarlet sel -B -N x=http://maven.apache.org/POM/4.0.0 \
        -t -m "$section" "${value_table[@]}" --nl "$xml_file"))
    IFS=$OLD_IFS
}

称呼:

locate_section_values "$pom_file_name" '/x:project/x:developers/x:developer' \
      -v 'x:id' -o '|' -v 'x:name' -o '|' -v 'x:email' -o '|' \
      -m 'x:roles/x:role' -v '.' -o ', ' -b -o '|' \
      -v 'x:organization' -o '|' -v 'x:organizationUrl' -o '|' \
      -v 'x:timezone'

循环开发人员并提取字段:

for developer in "${xml_values[@]}"; do
    # get | separated fields
    IFS='|' read id name email roles org orgUrl timezone <<<"$developer"

    if [ -n "$roles" ]; then # roles
        developer_roles_csv=${roles%, } # strip trailing comma
    fi

    echo "$name ($id) has roles: $developer_roles_csv."

done # developer
于 2013-01-29T00:09:09.390 回答
0

根据@npostavs提供的答案,我有以下工作:

function locate_section_values(){
  local xml_file=$1 # $local_project_dir/$fixed_name/pom.xml
  local section=$2 #/x:project/x:modules/x:module
  local value_table=${@:3}

  OLD_IFS=$IFS
  IFS=$'\n'
  xml_values=()
  xml_cmd="xmlstarlet sel -B -N x=\"http://maven.apache.org/POM/4.0.0\" \
      -t -m \"$section\" $value_table -nl $xml_file"
  xml_values=(`eval $xml_cmd`)
  IFS=$OLD_IFS
}

如果我这样称呼它,它会解析开发人员:

  # Developers
  locate_section_values $pom_file_name "/x:project/x:developers/x:developer" \
      -v \"x:id\" -o \"\|\" -v \"x:name\" -o \"\|\" -v \"x:email\" -o \"\|\" \
      -m \"x:roles/x:role\" -v \".\" -o \", \" -b -o \"\|\" \
      -v \"x:organization\" -o \"\|\" -v \"x:organizationUrl\" -o \"\|\" \
      -v \"x:timezone\"

我可以使用“developer_roles_csv=${4%??}”轻松删除尾随的“逗号和空格”:

  OLD_IFS=$IFS
  IFS=$'\n'
  for developer in ${xml_values[@]}; do
    IFS='|' 
    set $developer # split into $1, $2, etc using | as seperator

    ....

    if [ -n "${4}" ]; then # roles
      developer_roles_csv=${4%??} # strip trailing comma
      .....
    fi

    ....

  done # developer
  IFS=$OLD_IFS
于 2013-01-29T09:17:36.540 回答