Java: парсер XML - PullRequest
       23

Java: парсер XML

4 голосов
/ 05 августа 2009

У меня есть XML-ответ вроде этого -

<Response> <aa> <Fromhere> <a1>Content</a1> <a2>Content</a2> </Fromhere> </aa> </Response>

Я хочу извлечь все содержимое из <Fromhere> до </Fromhere> в строке. Возможно ли это сделать с помощью какой-либо строковой функции или с помощью анализатора XML?

Пожалуйста, совет.

Ответы [ 5 ]

4 голосов
/ 05 августа 2009

Вы можете попробовать подход XPath для простоты разбора XML:

InputStream response = new ByteArrayInputStream("<Response> <aa> "
        + "<Fromhere> <a1>Content</a1> <a2>Content</a2> </Fromhere> "
        + "</aa> </Response>".getBytes()); /* Or whatever. */

DocumentBuilder builder = DocumentBuilderFactory
        .newInstance().newDocumentBuilder();
Document doc = builder.parse(response);

XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("string(/Response/aa/FromHere)");
String result = (String)expr.evaluate(doc, XPathConstants.STRING);

Обратите внимание, что я не пробовал этот код. Может потребоваться настройка.

2 голосов
/ 05 августа 2009

Вы можете применить таблицу стилей XSLT для извлечения желаемого содержимого.

Эта таблица стилей должна соответствовать вашему примеру:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/Response/aa/Fromhere/*">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Примените его следующим образом (обработка исключений не включена):

String xml = "<Response> <aa> <Fromhere> <a1>Content</a1> <a2>Content</a2> </Fromhere> </aa> </Response>";
Source xsl = new StreamSource(new FileReader("/path/to/file.xsl");

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(xsl);
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

StringWriter out = new StringWriter();
transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(out));

System.out.println(out.toString());

Это должно работать с любой версией Java, начиная с 1.4.

2 голосов
/ 05 августа 2009

Через анализатор XML. Использование строковых функций для разбора XML - плохая идея ...
Помимо упомянутых выше руководств Sun, вы можете проверить DZone Refcardz на Java и XML , я обнаружил, что это было хорошее, краткое объяснение, как это сделать. Но, вероятно, по этой теме имеется множество веб-ресурсов, в том числе и на этом сайте.

0 голосов
/ 05 августа 2009

Один из вариантов - использовать StreamFilter :

class MyFilter implements StreamFilter {
  private boolean on;

  @Override
  public boolean accept(XMLStreamReader reader) {
    final String element = "Fromhere";
    if (reader.isStartElement() && element.equals(reader.getLocalName())) {
      on = true;
    } else if (reader.isEndElement()
        && element.equals(reader.getLocalName())) {
      on = false;
      return true;
    }
    return on;
  }
}

В сочетании с Трансформатором вы можете использовать это для безопасного анализа логически эквивалентной разметки, например:

<Response>
  <!-- <Fromhere></Fromhere> -->
  <aa>
    <Fromhere>
      <a1>Content</a1> <a2>Content</a2>
    </Fromhere>
  </aa>
</Response>

Демо-версия:

StringWriter writer = new StringWriter();

XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLStreamReader reader = inputFactory
    .createXMLStreamReader(new StringReader(xmlString));
reader = inputFactory.createFilteredReader(reader, new MyFilter());
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new StAXSource(reader), new StreamResult(writer));

System.out.println(writer.toString());

Это программный вариант подхода Массимилиано Флири .

0 голосов
/ 05 августа 2009

Это должно работать

import java.util.regex.*

Pattern p = Pattern.compile("<Fromhere>.*</Fromhere>");
Matcher m = p.matcher(responseString);
String whatYouWant = m.group();

Было бы немного более многословно использовать сканер, но это тоже может сработать.

Является ли это хорошей идеей для кого-то более опытного, чем я.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...