Input (fullInput
)
Представьте я следующее как InputStream
(или как String
в памяти считываются из этого потока):Как разобрать XML частично (только один уровень глубокий)
<?xml version="1.0" ?>
<root>
<element attr="val1"><x /><y /></element>
<element attr="val2"><y /></element>
<element attr="val3"><x /><x /></element>
<element attr="val4"><z /><y /></element>
</root>
Как я хочу использовать решение (bridgeXml
)
IProprietaryUnmarshaller UNMARSHALLER = ...;
List<Element> parseFullXml(String fullInput) throws UnmarshallException {
List<String> inputs = bridgeXml(fullInput);
List<Element> outputs = new ArrayList();
for(String input : inputs) {
Element e = UNMARSHALLER.unmarshall(input);
outputs.add(e);
}
return outputs;
}
Что я ищу
Я ищу реализацию/идею для bridgeXml
, где вход String
/*Stream
разбит на маленькие патроны строк, которые являются хорошо сформированными XML-документами (без объявления XML) сами по себе.
тривиальная реализацией Я хочу, чтобы избежать
В приведенных ниже реализации является ошибками, негибким и не должен быть использован, я ищу для надлежащих один с помощью какого-то библиотеки или XML-парсера!
List<String> bridgeXml(String input) {
// strip anything up to the opening root element, and LTrim the remainder
input = input.replaceAll("(?s)^.*<root.*?>\\s*", "");
// strip anything after the closing root element, and RTrim the remainder
input = input.replaceAll("(?s)\\s*</root.*$", "");
// split at </element> closing tags, not removing them (?<= does the magic)
return Arrays.asList(input.split("(?<=</element>)"));
}
Ограничения
- Входной XML не может быть изменен, и является полностью действительным XML.
- Собственный немаршаллер должен использоваться и не может быть изменен.
- Я ищу решение, в котором файл не XML-маршаллированный, XML-маршаллированный, проприетарный unmarshalled.
- (Не берите в XML/стиль кода Java, форматирование, видимость модификаторов и т.д.!
Эти упрощенные коды для облегчения общения.)
Solution (редактировать)
Я закончил написав эту статью ... Я закончил двойной анализ XML (см. getOuterXml
), потому что было преждевременно предполагать, что он медленный. После этого у меня есть огромный запрос БД, который медленнее.
protected <T> List<T> read(InputStream inputStream, String tagName) throws XMLStreamException,
TransformerException, DecodingException
{
List<T> result = new ArrayList<T>();
XMLInputFactory xmlFactory = XMLInputFactory.newInstance();
XMLStreamReader xmlReader = xmlFactory.createXMLStreamReader(inputStream, "ISO-8859-1");
while (xmlReader.hasNext()) {
xmlReader.next();
if (xmlReader.isStartElement() && tagName.equals(xmlReader.getLocalName())) {
String output = getOuterXml(xmlReader);
@SuppressWarnings("unchecked")
T object = (T) UNMARSHALLER.unmarshall(output);
result.add(object);
}
}
return result;
}
protected String getOuterXml(XMLStreamReader xmlr) throws TransformerException
{
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StringWriter stringWriter = new StringWriter();
transformer.transform(new StAXSource(xmlr), new StreamResult(stringWriter));
return stringWriter.toString();
}
protected <T> List<T> getObjects(String urlString, String tagName)
{
LOG.info("Downloading [{}] updates from [{}].", tagName, urlString);
HttpURLConnection conn = null;
InputStream inputStream = null;
try {
URL url = new URL(urlString);
conn = (HttpURLConnection) url.openConnection();
conn.connect();
inputStream = conn.getInputStream();
return read(inputStream, tagName);
} catch (Exception ex) {
String exceptionMessage = "Updating [" + tagName + "] from [" + urlString + "] failed.";
LOG.error(exceptionMessage, ex);
throw new MyFancyWrapperException(exceptionMessage, ex);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException ex) {
LOG.warn("Cannot close HTTP's input stream", ex);
}
}
if (conn != null) {
conn.disconnect();
}
}
}
Вы уже помечено свой вопрос с StAX. То, что я вам предлагаю. С его помощью вы можете передавать XML-документы или их части и использовать JAXB для синтаксического анализа действительного югу от xml. Вот что я уже делаю, чтобы разделить очень большие XML-документы с некоторыми интересными частями для unmarshaller. – wumpz