首先,我想提一下,这不是“
如何解析无效(格式错误/格式不正确)的XML”的副本?因为我没有给定的无效(或格式不正确)的XML文件,而是给定的任意Java
String
,它可能包含也可能不包含无效的XML字符。我想创建一个Document
包含Text
具有给定节点的DOM
String
,然后将其转换为文件。当文件解析为DOM时,Document
我想获得一个String
等于初始给定值的String
。我使用创建Text
节点,org.w3c.dom.Document#createTextNode(String data)
并使用获取字符串org.w3c.dom.Node#getTextContent()
。
如您在http://codingdict.com/questions/110317中所见,Text
XML文件中的节点存在一些无效字符。实际上,Text
节点有两种不同类型的“无效”字符。有预定义的实体,例如"
,&
,'
,<
和>
其自动地由DOM
API与逃脱"
,&
,'
,<
和>
在生成的文件是由DOM
API而复当文件被解析。现在的问题是,其他无效字符(例如'\u0000'
或)则不是这种情况'\uffff'
。解析文件时会发生异常,因为'\u0000'
和'\uffff'
是无效字符。
可能我必须实现一种以给定String
的方式对那些字符进行转义的方法,然后再将其提交给DOM
API,并在稍后得到String
回复时撤消该操作,对吗?有一个更好的方法吗?过去有人实施过这些或类似方法吗?
编辑:
这个问题被标记为Java中编码XML文本数据的最佳方法的重复吗?。我现在已经阅读了所有答案,但是没有一个能解决我的问题。所有答案都表明:
"
,&
,'
,<
,>
和几个。"&#number;"
将导致无效字符的异常,例如"�"
在分析文件时。"�"
(在某些库中被跳过)之类的非法字符。正如@VGR和@kjhughes在问题下方的注释中指出的那样,Base64确实是我问题的可能答案。现在,我确实有一个基于转义的问题的进一步解决方案。我已经写了2种功能escapeInvalidXmlCharacters(String string)
,并unescapeInvalidXmlCharacters(String string)
可以通过以下方式使用。
String string = "text#text##text#0;text" + '\u0000' + "text<text&text#";
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element element = document.createElement("element");
element.appendChild(document.createTextNode(escapeInvalidXmlCharacters(string)));
document.appendChild(element);
TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(new File("test.xml")));
// creates <?xml version="1.0" encoding="UTF-8" standalone="no"?><element>text##text####text##0;text#0;text<text&text##</element>
document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("test.xml"));
System.out.println(unescapeInvalidXmlCharacters(document.getDocumentElement().getTextContent()).equals(string));
// prints true
escapeInvalidXmlCharacters(String string)
和unescapeInvalidXmlCharacters(String string)
:
/**
* Escapes invalid XML Unicode code points in a <code>{@link String}</code>. The
* DOM API already escapes predefined entities, such as {@code "}, {@code &},
* {@code '}, {@code <} and {@code >} for
* <code>{@link org.w3c.dom.Text Text}</code> nodes. Therefore, these Unicode
* code points are ignored by this function. However, there are some other
* invalid XML Unicode code points, such as {@code '\u0000'}, which are even
* invalid in their escaped form, such as {@code "�"}.
* <p>
* This function replaces all {@code '#'} by {@code "##"} and all Unicode code
* points which are not in the ranges #x9 | #xA | #xD | [#x20-#xD7FF] |
* [#xE000-#xFFFD] | [#x10000-#x10FFFF] by the <code>{@link String}</code>
* {@code "#c;"}, where <code>c</code> is the Unicode code point.
*
* @param string the <code>{@link String}</code> to be escaped
* @return the escaped <code>{@link String}</code>
* @see <code>{@link #unescapeInvalidXmlCharacters(String)}</code>
*/
public static String escapeInvalidXmlCharacters(String string) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0, codePoint = 0; i < string.length(); i += Character.charCount(codePoint)) {
codePoint = string.codePointAt(i);
if (codePoint == '#') {
stringBuilder.append("##");
} else if (codePoint == 0x9 || codePoint == 0xA || codePoint == 0xD || codePoint >= 0x20 && codePoint <= 0xD7FF || codePoint >= 0xE000 && codePoint <= 0xFFFD || codePoint >= 0x10000 && codePoint <= 0x10FFFF) {
stringBuilder.appendCodePoint(codePoint);
} else {
stringBuilder.append("#" + codePoint + ";");
}
}
return stringBuilder.toString();
}
/**
* Unescapes invalid XML Unicode code points in a <code>{@link String}</code>.
* Makes <code>{@link #escapeInvalidXmlCharacters(String)}</code> undone.
*
* @param string the <code>{@link String}</code> to be unescaped
* @return the unescaped <code>{@link String}</code>
* @see <code>{@link #escapeInvalidXmlCharacters(String)}</code>
*/
public static String unescapeInvalidXmlCharacters(String string) {
StringBuilder stringBuilder = new StringBuilder();
boolean escaped = false;
for (int i = 0, codePoint = 0; i < string.length(); i += Character.charCount(codePoint)) {
codePoint = string.codePointAt(i);
if (escaped) {
stringBuilder.appendCodePoint(codePoint);
escaped = false;
} else if (codePoint == '#') {
StringBuilder intBuilder = new StringBuilder();
int j;
for (j = i + 1; j < string.length(); j += Character.charCount(codePoint)) {
codePoint = string.codePointAt(j);
if (codePoint == ';') {
escaped = true;
break;
}
if (codePoint >= 48 && codePoint <= 57) {
intBuilder.appendCodePoint(codePoint);
} else {
break;
}
}
if (escaped) {
try {
codePoint = Integer.parseInt(intBuilder.toString());
stringBuilder.appendCodePoint(codePoint);
escaped = false;
i = j;
} catch (IllegalArgumentException e) {
codePoint = '#';
escaped = true;
}
} else {
codePoint = '#';
escaped = true;
}
} else {
stringBuilder.appendCodePoint(codePoint);
}
}
return stringBuilder.toString();
}
请注意,这些功能可能效率很低,可以用更好的方式编写。随时发布建议以改进注释中的代码。
总之,我正在尝试解析中的xml。但是XMLSpy告诉我xml的格式不好。 我相信这xml中包含了一些无效字符()。因为如果我把它拿走。XMLSpy的验证已通过。我认为UTF-8编码不允许这种字符。但是如果我真的想加入这种角色呢。我应该应用哪种编码?谢谢
我将XML作为字符串传递给一个方法,并再次将其转换为XML来完成我的工作。 其正常工作正常,但当出现特殊字符时,如<代码> 我的XML字符串: 我的代码是: 错误: “=”是意外标记。预期标记为“;”。第1行,位置150。 完全错误为: 系统Xml。XmlException未由用户代码处理HResult=-2146232000消息=“=”是意外令牌。预期标记为“;”。第1行,位置150。源=系统。
问题内容: 您好,我正在从Web服务获取一个字符串。 我需要解析此字符串并获取错误消息中的文本? 我的字符串如下所示: 仅分析字符串还是将其转换为xml然后进行分析是否更好? 问题答案: 我将使用Java的XML文档库。有点混乱,但是可以。
问题内容: 您如何解析存储在Java字符串对象中的xml? Java的XMLReader仅从URI或输入流中解析XML文档。无法从包含xml数据的字符串进行解析? 现在,我有以下内容: 在我的处理程序上,我有这个: 提前致谢 问题答案: 该SAXParser的可以读取的的InputSource。 一个 InputSource的 可以采取 读者 在其构造 因此,您可以通过StringReader来解
我想要一个带有ANTLR的规则,将任何字符解析为数字、字符串特殊('@space)等,直到单词FOOTER(不包括) 我要解析的文本是这样的 我尝试使用此代码:在词法分析器中。 在解析器中。 但它不起作用。
问题内容: 我有一个无效的json字符串,如下所示, 我尝试使用JSON.parse将其转换为对象。但是,这不是有效的json字符串。是否有任何函数可以将这种无效格式转换为有效的json字符串或直接转换为对象? 问题答案: 如果您的示例语法与真实JSON相同,则JSONLint表示您需要对名称和值使用双引号。 仅在这种情况下,请使用以下替换调用: 但是,您首先应该尝试使用有效的Json。