Java 使用JAXB解组XML而无需取消字符
设想以下情况:我们从某个外部工具收到一个xml文件。最近在这个xml中,节点名或其richcontent标记中可能有一些转义字符,如下面的示例(简化):Java 使用JAXB解组XML而无需取消字符,java,xml,escaping,unmarshalling,Java,Xml,Escaping,Unmarshalling,设想以下情况:我们从某个外部工具收到一个xml文件。最近在这个xml中,节点名或其richcontent标记中可能有一些转义字符,如下面的示例(简化): 我是节点ä的注释ä! 在用JAXB解组文件后,这些转义字符将被取消转义。不幸的是,我需要他们保持现状,意味着逃脱。有没有什么方法可以避免在解封时将这些角色从中分离出来 在研究过程中,我发现了许多关于在出现相反问题的地方编组xml文件的问题,但这些问题也没有帮助我: 是否有可能用JAXB实现这一目标,或者我们甚至
我是节点ä的注释ä!
在用JAXB解组文件后,这些转义字符将被取消转义。不幸的是,我需要他们保持现状,意味着逃脱。有没有什么方法可以避免在解封时将这些角色从中分离出来
在研究过程中,我发现了许多关于在出现相反问题的地方编组xml文件的问题,但这些问题也没有帮助我:
是否有可能用JAXB实现这一目标,或者我们甚至必须考虑更改为不同的XML读取器API?
提前谢谢大家,,ymene您只需将
和#
替换为&#代码>因此调用
unmarshaller.unmarshal(new AmpersandingStream(new FileInputStream(...)));
及
对于任何xml解析器来说,源文档是否包含ä
,'ä;`或者ä
,为什么这对您的情况很重要?问题是:导入这些XML数据后,我们将其与程序数据合并。在这里,我们更改了一些细节,然后希望用xml将这些细节写回外部工具。由于我们没有构建另一个对象图来将数据封送回xml,因此我们欺骗了使用StAX,因为这在当时更简单。从那时起,直到现在我们还没有任何转义字符,不幸的是,外部工具仍然希望转义字符能够工作。注意:构建一个文档相对容易,因为这种方法会破坏XML(例如,编码为UTF-16;在CDATA节中放置符号等)下面是一个测试用例:
。代码查找序列&
。在CDATA中,这可能有问题,但是JAXB和CDATA呢?在别处,&
总是有意义的。@McDowell关于UTF-16你是对的,但我认为这不太可能。
unmarshaller.unmarshal(new AmpersandingStream(new FileInputStream(...)));
import java.io.IOException;
import java.io.InputStream;
/**
* Replaces numerical entities with their notation as text.
*/
public class AmpersandingStream extends InputStream {
private InputStream in;
private boolean justReadAmpersand;
private String lookAhead = "";
public AmpersandingStream(InputStream in) {
this.in = in;
}
@Override
public int read() throws IOException {
if (!lookAhead.isEmpty()) {
int c = lookAhead.codePointAt(0);
lookAhead = lookAhead.substring(Character.charCount(c));
return c;
}
int c = in.read();
if (c == (int)'#' && justReadAmpersand) {
c = (int)'a';
lookAhead = "mp;#";
}
justReadAmpersand = c == (int)'&';
return c;
}
@Override
public int available() throws IOException {
return in.available();
}
@Override
public void close() throws IOException {
in.close();
}
@Override
public synchronized void mark(int readlimit) {
in.mark(readlimit);
}
@Override
public boolean markSupported() {
return in.markSupported();
}
@Override
public int read(byte[] b) throws IOException {
return in.read(b);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return in.read(b, off, len);
}
@Override
public synchronized void reset() throws IOException {
in.reset();
}
@Override
public long skip(long n) throws IOException {
return in.skip(n);
}
}