如何在xml中整理像ú这样的东西?

时间:2016-05-18 14:28:39

标签: xml unicode utf-8 tidy

我有以下XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<authors><![CDATA[&#x00E3;  &#x00FA; ]]></authors>  
</root>

我想将&#x00FA;转换为ú。以下调用tidy的方法不起作用。有人知道调用它的正确方法是什么?

tidy --preserve-entities no --output-encoding utf8 tmp1.xml > tmp2.xml 

2 个答案:

答案 0 :(得分:2)

CDATA部分,如

<![CDATA[&#x00E3; &#x00FA;]]>

等同于

<![CDATA[ã ú]]>

在CDATA部分中,&<>等字符会失去其特殊含义,并按字面意思对待。所以上面的CDATA部分相当于

&amp;#x00E3; &amp;#x00FA;

您的转换不会“整理”您的XML文件,它实际上会更改字符数据。这就是为什么你不能用简单的工具进行你正在寻找的转换。此外,您通常不能盲目地应用正则表达式,因为您不想更改可能包含CDATA部分的XML文件的其他部分。

如果你真的想转换你所描述的文件,你应该使用XML库以你选择的脚本语言编写一个小程序。此程序应该只解码您希望转换发生的XML文件的那些部分中的实体。请参阅以下Perl脚本,例如:

use strict;
use XML::LibXML;

my $doc = XML::LibXML->new->parse_fh(\*STDIN);

# Process all text nodes within "authors" elements.
for my $authors_text ($doc->findnodes('//authors//text()')) {
    my $text = $authors_text->data;
    $text =~ s/&#x([0-9A-Fa-f]+);/chr(hex($1))/ge;
    $authors_text->setData($text);
}

print $doc->toString;

答案 1 :(得分:0)

在java中使用泛型模式搜索和替换。

以下搜索&# +可选x(十六进制)+数字+ ;

String fillInNumericEntities(String xml) {
    Pattern entityPattern = Pattern.compile("\\&#([Xx]?)([\\w]+);");
    StringBuffer sb = new StringBuffer(xml.length());
    Matcher m = entityPattern.matcher(xml);
    while (m.find()) {
         int numBase = m.group(1).isEmpty() ? 10 : 16;
         String number = m.group(2);
         try {
             int codePoint = Integer.parseInt(number, numBase);
             int[] codePoints = new int[] { codePoint };
             String ch = new String(codePoints, 0, 1);
             m.appendReplacement(sb, ch);
         } catch (NumberFormatException e) {
         }
    }
    m.appendTail(sb);
    return sb.toString();
}

备注:浏览器可以是将特殊字符自动转换为数字实体的来源,尤其是在缺少HTML <form accept-charset="UTF-8">的情况下。