Я пытаюсь разобрать XML на Java с помощью SAX. По этой причине я сделал себе UnitTest.XML не может быть проанализирован, когда String, без проблем при анализе из файла
Когда я пытаюсь разобрать XML из файла, все работает замечательно, но когда я пытаюсь разобрать тот же XML из строки синтаксические терпит неудачу и дает мне следующую ошибку:
java.net.MalformedURLException: no protocol: <?xml version="1.0" encoding="UTF-8"?>
<root>
<subnode>
<id>s1</id>
<name>Subnode one</name>
<value>11</value>
</subnode>
<subnode>
<id>s2</id>
<name>Subnode two</name>
<value>22</value>
</subnode>
</root>
at java.net.URL.<init>(URL.java:586)
at java.net.URL.<init>(URL.java:483)
at java.net.URL.<init>(URL.java:432)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:619)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:189)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:812)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:333)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:274)
at tests.xmlparsing.XMLParserTest.ParseStringTest(XMLParserTest.java:89)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Моему UnitTest-файл: http://pastebin.com/vd2zjWHu
package tests.xmlparsing;
import org.junit.Test;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.*;
import java.util.LinkedList;
import java.util.List;
import javax.xml.parsers.*;
import static org.junit.Assert.*;
/**
* Created by simonlammer on 14.03.15.
*/
public class XMLParserTest {
private static SAXHandler handler;
private static String xmlString;
static {
handler = new SAXHandler();
xmlString =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\r\n" +
"<root> " + "\r\n" +
" <subnode> " + "\r\n" +
" <id>s1</id> " + "\r\n" +
" <name>Subnode one</name> " + "\r\n" +
" <value>11</value> " + "\r\n" +
" </subnode> " + "\r\n" +
" <subnode> " + "\r\n" +
" <id>s2</id> " + "\r\n" +
" <name>Subnode two</name> " + "\r\n" +
" <value>22</value> " + "\r\n" +
" </subnode> " + "\r\n" +
"</root> ";
}
private SAXParser parser;
public XMLParserTest() throws ParserConfigurationException, SAXException {
this.parser = newSAXParser();
}
private SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser(); // throws ParserConfigurationException
return parser;
}
@Test
public void SAXParserNotNullTest() {
assertNotNull(parser);
}
@Test
public void SAXHandlerNotNullTest() {
assertNotNull(handler);
}
@Test
public void ParseFileTest() throws IOException, SAXException {
// create File
File file = new File("temporaryXMLFileUsedForUnitTest.xml");
try {
FileWriter fw = new FileWriter(file);
fw.write(xmlString);
fw.flush();
fw.close();
} catch (IOException e) {
fail("Could not create file");
}
// parse
handler.clearElements();
parser.parse(file, handler);
List<SampleElement> elements = handler.getElements();
// validate
validateElementList(elements);
// delete file
file.delete();
}
@Test
public void ParseStringTest() throws IOException, SAXException {
// parse
handler.clearElements();
parser.parse(xmlString, handler);
List<SampleElement> elements = handler.getElements();
// validate
validateElementList(elements);
}
private void validateElementList(List<SampleElement> elements) {
assertEquals(2, elements.size());
assertEquals("s1", elements.get(0).getId());
assertEquals("Subnode one", elements.get(0).getName());
assertEquals(11, elements.get(0).getValue());
assertEquals("s2", elements.get(1).getId());
assertEquals("Subnode two", elements.get(1).getName());
assertEquals(22, elements.get(1).getValue());
}
public static class SampleElement {
private String id;
private String name;
private int value;
public SampleElement(String id, String name, int value) {
this.id = id;
this.name = name;
this.value = value;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public int getValue() {
return value;
}
}
public static class SAXHandler extends DefaultHandler {
private LinkedList<SampleElement> elements;
private String id;
private String name;
private boolean tagId = false;
private boolean tagName = false;
private boolean tagValue = false;
private String value;
public SAXHandler() {
elements = new LinkedList<>();
}
public void clearElements() {
elements.clear();
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String str = new String(ch, start, length);
if (tagId) {
id = str;
} else if (tagName) {
name = str;
} else if (tagValue) {
value = str;
}
}
public List<SampleElement> getElements() {
return (LinkedList<SampleElement>) elements.clone();
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equalsIgnoreCase("id")) {
tagId = false;
} else if (qName.equalsIgnoreCase("name")) {
tagName = false;
} else if (qName.equalsIgnoreCase("value")) {
tagValue = false;
// create new SampleElement
if (id != null && name != null && value != null) {
int val = Integer.parseInt(value);
SampleElement element = new SampleElement(id, name, val);
elements.add(element);
// clear strings
id = name = value = null;
}
}
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("id")) {
tagId = true;
id = null;
} else if (qName.equalsIgnoreCase("name")) {
tagName = true;
name = null;
} else if (qName.equalsIgnoreCase("value")) {
tagValue = true;
value = null;
}
}
}
}
Вопрос: Почему это работает при разборе из файла, но не при разборе из строки? Как выполнить синтаксический анализ из строки с помощью анализатора SAX без получения этой ошибки?
Редактировать: Решение было найдено RealSkeptic, спасибо вам большое. Перегрузкой, которую я использовал, не должен был быть сам XML, а скорее путь к XML-файлу. Чтобы решить проблему, мне пришлось изменить «parser.parse (xmlString), обработчик);» на «parser.parse» (новый InputSource (новый StringReader (xmlString)), обработчик);