Замените несколько строк в XML, используя пару ключ-значение в файле CSV - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть дамп с нашего сервера приложений, который содержит XML из нескольких строк.Меня интересует идентификатор пользователя, который встроен в теги XML и в формате (lasfir1), как в приведенных ниже примерах XML:

<row>
  <string></string>
  <integer>2177</integer>
  <string>assignee =lasfir1 </string>
  <string>Firstname Lastname</string>
  <integer>10</integer>
  <string xsi:nil="true"/>
  <integer>450</integer>
</row>

<row>
  <string>#ffd600</string>
  <integer>2199</integer>
  <integer>23</integer>
  <integer>474</integer>
  <string>assignee</string>
  <string>lasfir1</string>
</row>

<row>
  <integer>1536</integer>
  <string>lasfir1</string>
  <integer>235</integer>
  <string>USER</string>
</row>

<row>
  <string>#ffd610</string>
  <integer>2200</integer>
  <integer>25</integer>
  <integer>464</integer>
  <string>assignee</string>
  <string>lisfar1</string>
</row>

Требуется преобразовать строку «lasfir1» только вего эквивалентный идентификатор электронной почты, который доступен в другом CSV (текстовом) файле, который имеет пару ключ-значение для идентификатора пользователя и идентификатора электронной почты:

FirstName.LastName@abc.com,lasfir1
FarstName.ListName@abc.com,lisfar1
LastName.FirstName@abc.com,firlas1

XML не всегда может быть одинаковым, но строкаэто будет тот, который нужно искать, а не образец того, что находится впереди или позади него.

Есть ли какой-нибудь простой способ прочитать пару ключ -> значение (в файле CSV), проверьте, есть ли ключ (userID) существует в XML-файле, а затем замените его на «значение» (идентификатор электронной почты)

Это необходимо для набора из 300+ комбинаций userID и Email ID, которые могут отсутствовать в XML.

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Проверьте это решение Perl one liner:

$ cat gagneet.csv
FirstName.LastName@abc.com,lasfir1
FarstName.ListName@abc.com,lisfar1
LastName.FirstName@abc.com,firlas1

$ cat gagneet.xml
<row>
  <string></string>
  <integer>2177</integer>
  <string>assignee =lasfir1 </string>
  <string>Firstname Lastname</string>
  <integer>10</integer>
  <string xsi:nil="true"/>
  <integer>450</integer>
</row>

. . . . 
. . . . 

$ perl -ne 'BEGIN { %kv=map{chomp;(split(",",$_))[1,0] } qx(cat gagneet.csv) ; $content=qx(cat gagneet.xml);while($content=~/(<row>)(.*?)(<\/row>)/smg) { $xml=$2;forea
ch $y (keys %kv) { $xml=~s/${y}/$kv{$y}/gm; } print "$1$xml$3\n"; } exit } '
<row>
  <string></string>
  <integer>2177</integer>
  <string>assignee =FirstName.LastName@abc.com </string>
  <string>Firstname Lastname</string>
  <integer>10</integer>
  <string xsi:nil="true"/>
  <integer>450</integer>
</row>
<row>
  <string>#ffd600</string>
  <integer>2199</integer>
  <integer>23</integer>
  <integer>474</integer>
  <string>assignee</string>
  <string>FirstName.LastName@abc.com</string>
</row>
<row>
  <integer>1536</integer>
  <string>FirstName.LastName@abc.com</string>
  <integer>235</integer>
  <string>USER</string>
</row>
<row>
  <string>#ffd610</string>
  <integer>2200</integer>
  <integer>25</integer>
  <integer>464</integer>
  <string>assignee</string>
  <string>FarstName.ListName@abc.com</string>
</row>

Если вы хотите редактировать только между тегами, тогда

$ perl -ne 'BEGIN { %kv=map{chomp;(split(",",$_))[1,0] } qx(cat gagneet.csv) ; $content=qx(cat gagneet.xml);while($content=~/(<row>)(.*?)(<\/row>)/smg) { $xml=$2;forea
ch $y (keys %kv) { $xml=~s/<string>${y}<\/string>/<string>$kv{$y}<\/string>/gm; } print "$1$xml$3\n"; } exit } '
0 голосов
/ 21 ноября 2018

Создан скрипт с использованием Python3, который принимает входные данные в виде CSV и XML-файла и выводит XML-файл с изменениями.Команда:

python xml_converter.py –csvfile file.csv –xmlfile file.xml –outfile output_file.xml

Не полностью оптимизирована, как хотелось бы, чтобы она работала в одном потоке, и предполагается, что файлы имеют кодировку utf-8.

usage: Replace username to user email of a given xml file
       [-h] --csvfile CSVFILE --xmlfile XMLFILE --outfile OUTFILE

optional arguments:
  -h, --help         show this help message and exit
  --csvfile CSVFILE  csv file that provide user name and email pair
  --xmlfile XMLFILE  xml file that to be searched and replaced
  --outfile OUTFILE  output file name

Базовый сценарий:

class XMLConvert:
    def __init__(self, csv, xml, out):
        self._csv = csv
        self._xml = xml
        self._out = out

        self._kv_dict = self.prepare_kv_dict()

    def prepare_kv_dict(self):
        with open(self._csv, newline='', encoding='utf-8') as f:
            reader = csv.reader(f)
            result = dict()
            for row in reader:
                result[row[1]] = row[2]
        return result

    def convert(self):
        with open(self._xml, 'r', encoding='utf-8') as f:
            for line in f:
                _line = self.convert_line(line)
                yield _line

    def convert_line(self, line):
        # self._kv_dict = {'lasfir1': 'First.Name@abc.com'}
        for k, v in self._kv_dict.items():
            if k.lower() in line:
                # print(line)
                return re.sub(r'{}'.format(k), v, line)
        return line

    def start(self):
        with open(self._out, 'w', encoding='utf-8') as f:
            for line in self.convert():
                f.write(line)


if __name__ == '__main__':
    csv_file, xml_file, out_file = parse_args()
    converter = XMLConvert(csv_file, xml_file, out_file)
    converter.start()

Я пытаюсь добавить потоки и изменить его соответствующим образом, чтобы оптимизировать его работу.Если у кого-то есть лучший способ, пожалуйста, сообщите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...