Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对于超过3.0的Unicode版本,如何将Java字符串转换为xml实体?_Java_Unicode_Unicode String_Xml Entities - Fatal编程技术网

对于超过3.0的Unicode版本,如何将Java字符串转换为xml实体?

对于超过3.0的Unicode版本,如何将Java字符串转换为xml实体?,java,unicode,unicode-string,xml-entities,Java,Unicode,Unicode String,Xml Entities,要将java字符转换为xml实体,我可以对字符串中的每个字符执行以下操作: buf.append("&#x"+ Integer.toHexString(c | 0x10000).substring(1) +";"); 然而,根据其他stackoverflow问题,这只适用于Unicode 3.0 如果我使用UTF-8读取器读入一个字符串,那么该字符串可能包含通过Unicode 6.0实现的格式的字符(因为根据javadoc,Java7支持Unicode 6.0) 一旦我有了那个字符串,

要将java字符转换为xml实体,我可以对字符串中的每个字符执行以下操作:

buf.append("&#x"+ Integer.toHexString(c | 0x10000).substring(1) +";");
然而,根据其他stackoverflow问题,这只适用于Unicode 3.0

如果我使用UTF-8读取器读入一个字符串,那么该字符串可能包含通过Unicode 6.0实现的格式的字符(因为根据javadoc,Java7支持Unicode 6.0)


一旦我有了那个字符串,我怎么能把它写成xml实体呢?理想情况下,我会使用一些api,随着unicode新版本的推出,这些api将继续工作。

或者您使用的术语不正确,或者这里有很多混淆

和#x
字符参考符号仅指定一个数字码点;它独立于任何读取器或解析器使用的Unicode版本

您的代码实际上只与Unicode 1.x兼容,因为它假定字符的数值小于216。从Unicode 2.0开始,这不是一个正确的假设。一些字符由单个Java
char
表示,而其他字符由两个Java
char
表示(称为)

我不确定什么是“UTF-8阅读器”。A只读取
char
值,不知道UTF-8或任何其他字符集,除了使用A使用UTF-8编码(或特定字符集解码器使用的任何编码)将字节转换为字符

在任何情况下,读取器都不会解析XML
和#x
字符引用符号。为此,必须使用XML解析器

Java已知的Unicode版本不会影响读取器或XML解析器,因为读取器或XML解析器不会以任何方式查阅Unicode数据库。这些字符在解析时仅被视为数值。在任何Unicode版本中,它们是否对应于指定的代码点都不会被考虑

最后,要将字符串写成XML,可以使用:

静态字符串toXML(字符串s){
格式化程序格式化程序=新格式化程序();
int len=s.length();
对于(int i=0;i126 | | c=='&'| | c=='){
格式(&#x%x;”,c);
}否则{
格式化程序。格式(“%c”,c);
}
}
返回格式化程序.toString();
}
如您所见,没有依赖Unicode版本的代码,因为字符只是数值。每个数值是否为指定的Unicode码点并不相关


(我的第一个倾向是使用XMLStreamWriter类,但事实证明,使用非Unicode编码(如ISO-8859-1或US-ASCII)的XMLStreamWriter在Java 1.8.0_05中没有正确地将代理项对作为单字符实体输出。)

或者您使用的术语不正确,或者这里有很多混乱

和#x
字符参考符号仅指定一个数字码点;它独立于任何读取器或解析器使用的Unicode版本

您的代码实际上只与Unicode 1.x兼容,因为它假定字符的数值小于216。从Unicode 2.0开始,这不是一个正确的假设。一些字符由单个Java
char
表示,而其他字符由两个Java
char
表示(称为)

我不确定什么是“UTF-8阅读器”。A只读取
char
值,不知道UTF-8或任何其他字符集,除了使用A使用UTF-8编码(或特定字符集解码器使用的任何编码)将字节转换为字符

在任何情况下,读取器都不会解析XML
和#x
字符引用符号。为此,必须使用XML解析器

Java已知的Unicode版本不会影响读取器或XML解析器,因为读取器或XML解析器不会以任何方式查阅Unicode数据库。这些字符在解析时仅被视为数值。在任何Unicode版本中,它们是否对应于指定的代码点都不会被考虑

最后,要将字符串写成XML,可以使用:

静态字符串toXML(字符串s){
格式化程序格式化程序=新格式化程序();
int len=s.length();
对于(int i=0;i126 | | c=='&'| | c=='){
格式(&#x%x;”,c);
}否则{
格式化程序。格式(“%c”,c);
}
}
返回格式化程序.toString();
}
如您所见,没有依赖Unicode版本的代码,因为字符只是数值。每个数值是否为指定的Unicode码点并不相关


(我的第一个倾向是使用XMLStreamWriter类,但事实证明,使用非Unicode编码(如ISO-8859-1或US-ASCII)的XMLStreamWriter无法正确地将代理项对作为单字符实体输出,如Java 1.8.005)

最初,Java支持Unicode 1.0,将字符长度设为16位,但Unicode 2.0引入了代理字符机制,以支持比16位允许的字符数更多的字符,因此Java字符串变成了UTF-16编码的字符串;这意味着一些字符需要两个Java字符来表示,它们被称为高代理字符和低代理字符

要知道字符串中的哪些字符实际上是高/低代理项对,可以使用
字符
中的实用方法:

Character.isHighSurrogate(myChar); // returns true if myChar is a high surrogate
Character.isLowSurrogate(myChar); // same for low surrogate

Character.isSurrogate(myChar); // just to know if myChar is a surrogate
一旦您知道哪些字符是高代理或低代理,就需要使用以下方法将每对字符转换为unicode码点:

int codePoint = Character.toCodePoint(highSurrogate, lowSurrogate);
因为一段代码胜过千言万语,所以这是一个将xml字符引用替换为非us ascii c的示例方法
int codePoint = Character.toCodePoint(highSurrogate, lowSurrogate);
public static String replaceToCharEntities(String str) {
    StringBuilder result = new StringBuilder(str.length());

    char surrogate = 0;
    for(char c: str.toCharArray()) {

        // if char is a high surrogate, keep it to match it
        // against the next char (low surrogate)
        if(Character.isHighSurrogate(c)) {
            surrogate = c;
            continue;
        }

        // get codePoint
        int codePoint;
        if(surrogate != 0) {
            codePoint = Character.toCodePoint(surrogate, c);
            surrogate = 0;
        } else {
            codePoint = c;
        }

        // decide wether using just a char or a character reference
        if(codePoint < 0x20 || codePoint > 0x7E || codePoint == '<'
                || codePoint == '>' || codePoint == '&' || codePoint == '"'
                || codePoint == '\'') {
            result.append(String.format("&#x%x;", codePoint));
        } else {
            result.append(c);
        }
    }

    return result.toString();
}