BASH чтение данных из XML и копирование их в определенные поля в текстовом файле - PullRequest
0 голосов
/ 30 марта 2020

У меня есть конкретная c проблема, в которой я не могу найти решение. У меня есть два файла. Файл XML и текстовый файл.

Фрагмент из XML файла ниже:

<furnidata>
<roomitemtypes>
<furnitype id="13" classname="shelves_norja">
<revision>61856</revision>
<defaultdir>0</defaultdir>
<xdim>1</xdim>
<ydim>1</ydim>
<partcolors>
<color>#ffffff</color>
<color>#F7EBBC</color>
</partcolors>
<name>Boekenkast</name>
<description>Bewaar hier je frutsels en kunstboeken</description>
<adurl/>
<offerid>5</offerid>
<buyout>1</buyout>
<rentofferid>-1</rentofferid>
<rentbuyout>0</rentbuyout>
<bc>1</bc>
<excludeddynamic>0</excludeddynamic>
<customparams/>
<specialtype>1</specialtype>
<canstandon>0</canstandon>
<cansiton>0</cansiton>
<canlayon>0</canlayon>
<furniline>iced</furniline>
</furnitype>

Фрагмент из текстового файла ниже:

["20_credits","20 Credits",""],["220c_100d","50 procent korting op 220 Credits","220 credits en diamanten voor de prijs van 110 credits! Aanbieding is 48 uur beschikbaar en beperkt tot één per persoon."],["22_credits","22 Credits",""],["25credit_prize_14","25 Credits!",""],["2credit_prize_14","2 Credits!",""],["3-giveaway3","3-giveaway3",""]

Моя проблема: Я намерен скопировать каждый classname = "" из файла XML в первый "" между каждым [] где имя и описание из XML соответствуют имени (второе "") и описанию (третье "") из текстового файла. Проблема в том, что некоторые имена и описания встречаются дважды или более. Например, комбинация «Boekenkast» и «Bewaar hier je frutsels en kunstboeken» в общей сложности встречается 7 раз, каждый с другим именем класса.

XML отсортировано по id, но текстовый файл полностью перепутан.

Есть идеи, как подойти к этому с bash? Я далёк от вундеркиндов.

Если я не смог достаточно ясно объяснить это здесь, не стесняйтесь оставлять реакцию, я немедленно обновлю свой вопрос.

1 Ответ

0 голосов
/ 30 марта 2020

Кажется, что нет единой строчки, чтобы решить эту проблему, но вот мое мнение.

Вы можете использовать jq для перебора массива верхнего уровня, имени запроса и описания для каждого вложенного 3- массив, запросите файл XML для атрибута classname элементов furnitype, которые имеют дочерние узлы name & description со значениями из JSON, затем обновите JSON с этим именем класса.

#!/bin/bash

IN_JSON=input.json
IN_XML=input.xml
OUT_JSON=output.json

cat $IN_JSON > $OUT_JSON
XML=$(cat $IN_XML)
JSON=$(cat $IN_JSON)

JSON_ITEMS_N=`echo "$JSON" | jq '.|length'`

for (( I=0; I<$JSON_ITEMS_N; I++ )) do
    (( $I % 10 == 0 )) && echo "Item $I"

    # Querying the name & description entries from the JSON list.
    XML_N=`echo "$JSON" | jq -cr .[$I][1]`
    XML_D=`echo "$JSON" | jq -cr .[$I][2]`

    # Querying the found values from the XML file.
    XML_CLASS=$(echo $XML | xpath -q -e "//furnitype[name=\"$XML_N\" and description=\"$XML_D\"]/@classname")
    for CN in ${XML_CLASS[@]}; do
        XML_CLASS=$CN
        # Using the first encountered classname.
        # Remove break to use the last one.
        break
    done
    XML_CLASS="${XML_CLASS}"
    XML_CLASS=${XML_CLASS#*\"}
    XML_CLASS=${XML_CLASS%\"}

    if [[ $XML_CLASS != "" ]]; then
        echo "Found '$XML_N' / '$XML_D', classname is $XML_CLASS"
        # Updating the entire input JSON and saving it right to the output file.
        # Although map() iterates over entire file contents, the if clause within map()
        # limits it to only the needed entries (those with proper name & desc).
        JSON=$(echo "$JSON" | jq -cr ". | map(if .[1]==\"$XML_N\" and .[2]==\"$XML_D\" then .[0]=\"$XML_CLASS\" else . end)")
    fi
done

echo -n "$JSON" > $OUT_JSON
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...