У меня есть XML-файлы, которые содержат символы <
, >
, &
.Например:
<?xml version="1.0" encoding="utf-8"?>
<test>
<medi>bla bla >12 bla</medi>
<diag>bla & bla <12</diag>
</test>
Эти символы зарезервированы для нотации XML и должны быть заменены экранирующими строками <
, >
, &
.Это относится также к кавычкам ("-> "
) и апострофам ('-> '
).
Вот что мне нравится получать:
<?xml version="1.0" encoding="utf-8"?>
<test>
<medi>bla bla >12 bla</medi>
<diag>bla & bla <12</diag>
</test>
Обычно яиспользуйте регулярные выражения с perl или sed. Но, искренне, у меня ничего не получилось. Сложность состоит в том, чтобы избежать замены соответствующих XML-символов, таких как <
и >
и &
escape-строк.
Чтобы сделатьэто ясно, что я имею в виду, я поставил решение с Perl, который не работает:
use strict;
use warnings;
my $input = $ARGV[0];
my $output = $ARGV[1];
open INPUT, $input or die "Couldn't open file $input, $!";
open OUTPUT, ">$output" or die "Couldn't open file $output, $!";
my $rec;
while (<INPUT>) {
$rec = $_;
print $rec;
$rec =~ s/(<medi>.*)<(.*<\/medi>)/$1<$2/g;
$rec =~ s/(<medi>.*)>(.*<\/medi>)/$1>$2/g;
$rec =~ s/(<medi>.*)&(.*<\/medi>)/$1&$2/g;
$rec =~ s/(<medi>.*)'(.*<\/medi>)/$1'$2/g;
$rec =~ s/(<medi>.*)"(.*<\/medi>)/$1"$2/g;
$rec =~ s/(<diag>.*)<(.*<\/diag>)/$1<$2/g;
$rec =~ s/(<diag>.*)>(.*<\/diag>)/$1>$2/g;
$rec =~ s/(<diag>.*)&(.*<\/diag>)/$1&$2/g;
$rec =~ s/(<diag>.*)'(.*<\/diag>)/$1'$2/g;
$rec =~ s/(<diag>.*)"(.*<\/diag>)/$1"$2/g;
print $rec;
print OUTPUT $rec;
}
close INPUT;
close OUTPUT;
Это дает мне:
<?xml version="1.0" encoding="utf-8"?>
<test>
<medi>bla bla &gt;12 bla</medi>
<diag>bla & bla &lt;12</diag>
</test>
Что происходит:
- Амперсанд
>
был заменен на &
, который не предназначен - Амперсанд на
<diag> bla & bla ...
не заменен
Я уверен, что есть регулярное выражение, которое может решитьэта проблема. Но если есть совершенно другой способ сделать xml правильно сформированным, я открыт для этого.