SAX 解析器字符方法不收集所有内容
SAX Parser characters method doesn't collect all content
我正在使用 SAX 解析器解析 XML 并且工作正常。
我在 XML 中有以下标签。
<value>•CERTASS >> Certass</value>
这里我期望'•CERTASS >> Certass'作为输出。但下面的代码 returns 仅 Certass
。 value
标签的特殊字符有问题吗?
public void characters(char[] buffer, int start, int length) {
temp = new String(buffer, start, length);
}
不能保证 characters()
方法在一个元素 中只会 运行 一次。
如果你将内容存储在String
中,而characters()
方法恰好运行两次,你只会从第二次运行中获取内容.字符方法 运行s 第二次将覆盖第一次存储的 temp
变量的内容。
要解决这个问题,请使用 StringBuilder
和 append()
characters()
中的内容,然后处理 endElement()
中的内容。例如:
DefaultHandler handler = new DefaultHandler() {
private StringBuilder stringBuilder;
@Override
public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
stringBuilder = new StringBuilder();
}
public void characters(char[] buffer, int start, int length) {
stringBuilder.append(new String(buffer, start, length));
}
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println(stringBuilder.toString());
}
};
解析 String
“<value>•CERTASS >> Certass</value>
” 和上面的处理程序给出输出:
?CERTASS >> Certass
希望对您有所帮助。
前几天我 运行 遇到了这个问题,事实证明这是因为 CCharacters 方法被多次调用,以防这些字符中的任何一个包含在值中:
" "
' '
< <
> >
& &
还要注意值内的换行符/换行符!!!
如果 xml 在没有您控制的情况下换行,字符方法也将为语句中的每一行调用,另外它将 return 换行! (需要手动依次去掉)
处理所有这些问题的示例处理程序是这个:
DefaultHandler handler = new DefaultHandler() {
private boolean isInANameTag = false;
private String localname;
private StringBuilder elementContent;
@Override
public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
if (qname.equalsIgnoreCase("myfield")) {
isInMyTag = true;
this.localname = localname;
this.elementContent = new StringBuilder();
}
}
public void characters(char[] buffer, int start, int length) {
if (isInMyTag) {
String content = new String(ch, start, length);
if (StringUtils.equals(content.substring(0, 1), "\n")) {
// remove leading newline
elementContent.append(content.substring(1));
} else {
elementContent.append(content);
}
}
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qname.equalsIgnoreCase("myfield")) {
isInMyTag = false;
// do something with elementContent.toString());
System.out.println(elementContent.toString());
this.localname = "";
}
}
}
我正在使用 SAX 解析器解析 XML 并且工作正常。
我在 XML 中有以下标签。
<value>•CERTASS >> Certass</value>
这里我期望'•CERTASS >> Certass'作为输出。但下面的代码 returns 仅 Certass
。 value
标签的特殊字符有问题吗?
public void characters(char[] buffer, int start, int length) {
temp = new String(buffer, start, length);
}
不能保证 characters()
方法在一个元素 中只会 运行 一次。
如果你将内容存储在String
中,而characters()
方法恰好运行两次,你只会从第二次运行中获取内容.字符方法 运行s 第二次将覆盖第一次存储的 temp
变量的内容。
要解决这个问题,请使用 StringBuilder
和 append()
characters()
中的内容,然后处理 endElement()
中的内容。例如:
DefaultHandler handler = new DefaultHandler() {
private StringBuilder stringBuilder;
@Override
public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
stringBuilder = new StringBuilder();
}
public void characters(char[] buffer, int start, int length) {
stringBuilder.append(new String(buffer, start, length));
}
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println(stringBuilder.toString());
}
};
解析 String
“<value>•CERTASS >> Certass</value>
” 和上面的处理程序给出输出:
?CERTASS >> Certass
希望对您有所帮助。
前几天我 运行 遇到了这个问题,事实证明这是因为 CCharacters 方法被多次调用,以防这些字符中的任何一个包含在值中:
" "
' '
< <
> >
& &
还要注意值内的换行符/换行符!!! 如果 xml 在没有您控制的情况下换行,字符方法也将为语句中的每一行调用,另外它将 return 换行! (需要手动依次去掉)
处理所有这些问题的示例处理程序是这个:
DefaultHandler handler = new DefaultHandler() {
private boolean isInANameTag = false;
private String localname;
private StringBuilder elementContent;
@Override
public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
if (qname.equalsIgnoreCase("myfield")) {
isInMyTag = true;
this.localname = localname;
this.elementContent = new StringBuilder();
}
}
public void characters(char[] buffer, int start, int length) {
if (isInMyTag) {
String content = new String(ch, start, length);
if (StringUtils.equals(content.substring(0, 1), "\n")) {
// remove leading newline
elementContent.append(content.substring(1));
} else {
elementContent.append(content);
}
}
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qname.equalsIgnoreCase("myfield")) {
isInMyTag = false;
// do something with elementContent.toString());
System.out.println(elementContent.toString());
this.localname = "";
}
}
}