LINUX.ORG.RU

Заменить пробелы в XML файле

 ,


0

1

Всем привет!

Прислали мне тут, типа, XML файл, который с XML на самом-то деле не совместим. Файл очень большой и примерно следующего содержания:

	<Mode Number>1</Mode Number>
	<Min Set Temp>200</Min Set Temp>
	<Max Set Temp>550</Max Set Temp>
	<Default Temp>350</Default Temp>


Понятно, что в XML файле нельзя использовать пробелы в именах.

Как можно просто заменить пробелы на «_» для имён XML узлов? Т.е. только внутри «<» и «>» чтоб получилось:

	<Mode_Number>1</Mode_Number>
	<Min_Set_Temp>200</Min_Set_Temp>
	<Max_Set_Temp>550</Max_Set_Temp>
	<Default_Temp>350</Default_Temp>


Всем заранее Спасибо,


Думаю, это проще всего на C сделать, лови:

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main() {
  errno = 0;
  int tag = 0;
  while (1) {
    int c = getc(stdin);
    if (c == EOF) {
      if (errno) fprintf(stderr, "%s\n", strerror(errno));
      return errno;
    };

    switch (c) {
      case '<':
        tag = 1;
        break;
      case ' ':
        if (tag) c = '_';
        break;
      case '>':
        tag = 0;
        break;
    };

    if (putc(c, stdout) == EOF) {
      fprintf(stderr, "%s\n", strerror(errno));
      return errno;
    };
  };
};
XML надо подать на stdin.

Jini ★★
()
Последнее исправление: Jini (всего исправлений: 2)

Что мешает сделать замену в любом текстовом редакторе? Или поля постоянно разные?

RazrFalcon ★★★★★
()
Ответ на: комментарий от zolden

Нуачо, прикольно же, примитивный конечный автомат. Расскажи мне как это на чём-то другом сделать? sed 's/ /_/g' не катит из-за возможных пробелов в значениях.

Jini ★★
()
Ответ на: комментарий от Jini

Расскажи мне как это на чём-то другом сделать? sed 's/ /_/g' не катит из-за возможных пробелов в значениях.

sed не знаю дальше примитивных замен на регулярках, так что за него не скажу, но C тут и вправду ни к чему. Задача решается элементарно в «скриптовых» языках с нормальной поддержкой строк, вот тебе однострочник на Ruby:

$ ruby -pe 'gsub(%r|</?[^>]+>|) { |m| m.tr " ", "_" }' input.txt
	<Mode_Number>1</Mode_Number>
	<Min_Set_Temp>200</Min_Set_Temp>
	<Max_Set_Temp>550</Max_Set_Temp>
	<Default_Temp>350</Default_Temp>
theNamelessOne ★★★★★
()
Последнее исправление: theNamelessOne (всего исправлений: 1)
Ответ на: комментарий от Jini

sed 's/ /_/g' не катит из-за возможных пробелов в значениях.

$ echo "<Mode Number>1</Mode Number>
<Min Set Temp>200</Min Set Temp>
<Max Set Temp>550</Max Set Temp>
<Default Temp>35 0</Default Temp>" | sed ':a;s/\(<[^> ]\+\) \([^>]\+>\)/\1_\2/g;ta'

<Mode_Number>1</Mode_Number>
<Min_Set_Temp>200</Min_Set_Temp>
<Max_Set_Temp>550</Max_Set_Temp>
<Default_Temp>35 0</Default_Temp>
Kroz ★★★★★
()
Ответ на: комментарий от theNamelessOne
perl -npe 's{<(.*?)>}{"<" . ($1 =~ s/ /_/gr) . ">"}ge'

Хм, ну ладно, зато было весело. ТС, кстати, сказал, что файл большой, потому я и зацепился за C. Но тестить мне теперь уже лень.

Jini ★★
()
Последнее исправление: Jini (всего исправлений: 1)
Ответ на: комментарий от Kroz

Неплохое решение. С sed -r было бы ещё лучше.

Jini ★★
()

sed -i.backup -r ':n; s/(<.*) (.*>)/\1_\2/; tn' filename
Должно быть так. -i.backup на случай, если я ошибся.
Он пробует между <> находить пробел, менять на подчёркивание, делать это в цикле пока может.

evilface ★★
()
Ответ на: комментарий от evilface

sed -r ':n; s/(<[^>]*) (.*>)/\1_\2/; tn'
Вот такой фикс. Проверил, работает. Если не будет чего-нибудь вроде <tag <tag2>></tag>, так можно сломать при желании. Но тогда это совсем уже не XML, даже простив пробелы.

evilface ★★
()
Ответ на: комментарий от Jini

Расскажи мне как это на чём-то другом сделать?

А смысл? Тебе дали рабочее решение ж.

$ gcc -o xml_fixer xml_fixer.c
$ cat bad-file.xml | ./xml_fixer > good-file.xml
KivApple ★★★★★
()

Самое правильное решение тут дающему вправить карму.

anonymous
()
Ответ на: комментарий от KivApple

А смысл? Тебе дали рабочее решение ж.

Я его и написал, смотри внимательнее :)

Jini ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.