Как извлечь только элементы верхнего уровня в xml ответе дерева в Linux сценарии оболочки? - PullRequest
0 голосов
/ 22 января 2020

Ниже приведен сценарий оболочки, который отображает список имен и manager_add

name=($(grep -oP '(?<=name>)[^<]+' <<< "$vsppProxy_res"))

for i in ${!name[*]}
do
  echo "$i" "${name[$i]}"
  done

managers=($(grep -oP '(?<=manager_addr>)[^<]+' <<< "$vsppProxy_res"))

for i in ${!managers[*]}
do
  echo "$i" "${managers[$i]}"
  done

. Выходные данные:

0 name0 1 name1 2 name2 3 name3 .... .................... ........................ ...... .................. ........................ 0 manager_add0 1 manager_add1 2 manager_add2 .. ...................... ........................

Ответ xml содержит 3 элемента верхнего уровня, таких как <elem id="0">, и снова каждый элемент верхнего уровня содержит подэлементы, такие как <elem id="0">, в зависимости от размера. Но требуется требование извлечь только элемент верхнего уровня <elem id="0">

Пример xml выглядит следующим образом:

<X>
<regs>
<elem id="0">
<id>1</id>
<name>name0</name>
<warn>1</warn>
<manager_addr>manager_addr0</manager_addr>
<warn_desc>
<size>14</size>
<elem id="0">
<sev>2</sev>
<description>description</description>
<warning_id>1</warning_id>
<deployment_id>1</deployment_id>
<context_id>00</context_id>
<num_of_occurrences>1</num_of_occurrences>
<deployment_name>prod1</deployment_name>
</elem>
<elem id="1">
<sev>2</sev>
<description>description</description>
<warning_id>1</warning_id>
<deployment_id>1</deployment_id>
<context_id>00</context_id>
<num_of_occurrences>1</num_of_occurrences>
<deployment_name>prod1</deployment_name>
</elem>
</warn_desc>
</elem>
<elem id="1">
<id>2</id>
<name>name1</name>
<warn>1</warn>
<manager_addr>manager_addr1</manager_addr>
<warn_desc>
<size>1</size>
<elem id="0">
<sev>3</sev>
<description>description</description>
<warning_id>2</warning_id>
<context_id>00</context_id>
<num_of_occurrences>1</num_of_occurrences>
</elem>
</warn_desc>
</elem>
</regs>
</X>

Ожидаемый результат должен быть:

Менеджер: name0 manager_add0 ........................ .................... .... ........................

Пожалуйста, предоставьте ваши предложения. Спасибо.

1 Ответ

0 голосов
/ 22 января 2020

Попытка использовать регулярные выражения для разбора XML - это Плохая идея . Вы должны использовать XML -осведомленные инструменты. Один очевидный выбор для преобразования документа XML: XSLT .

Рассмотрим следующий сценарий оболочки, который применяет таблицу стилей XSLT к файлу, переданному ему в командной строке:

#!/bin/sh

# Use a temporary file for the XSLT stylesheet
stylesheet=$(mktemp)
cat >"$stylesheet" <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text" encoding="UTF-8" />
  <xsl:variable name="newline"><xsl:text>
</xsl:text></xsl:variable>
  <xsl:template match="/X">
    <xsl:for-each select="regs/elem">
      <xsl:value-of
          select="concat('Manager: ', name, ' ', manager_addr, $newline)" />
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
EOF

# Adjust as needed for whichever xslt processor you want to use
xsltproc "$stylesheet" "$1"
# xalan -xsl "$stylesheet" -in "$1"
# xmlstarlet tr "$stylesheet" "$1"

rm -f "$stylesheet"

Использование:

$ ./transform.sh input.xml
Manager: name0 manager_addr0
Manager: name1 manager_addr1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...