#java #xml
#java #xml
Вопрос:
Мне нужно просто прочитать значение одного атрибута внутри XML-файла, используя java. XML будет выглядеть примерно так:
<behavior name="Fred" version="2.0" ....>
и мне просто нужно прочитать версию. Может ли кто-нибудь указать направление ресурса, который показал бы мне, как это сделать?
Комментарии:
1. Это хороший пример того, почему простые вещи не всегда выполняются легко. Несмотря на то, что большинство фреймворков Java в значительной степени полагаются на XML, инструменты, доступные для реальной работы с XML в Java, довольно громоздки.
Ответ №1:
Вам не нужна навороченная библиотека — для этого довольно легко читать и записывать простые старые JAXP-версии DOM и XPath. Что бы вы ни делали, не используйте регулярное выражение.
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
public class GetVersion {
public static void main(String[] args) throws Exception {
XPath xpath = XPathFactory.newInstance().newXPath();
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse("file:////tmp/whatever.xml");
String version = xpath.evaluate("//behavior/@version", doc);
System.out.println(version);
}
}
Ответ №2:
JAXB для краткости:
private static String readVersion(File file) {
@XmlRootElement class Behavior {
@XmlAttribute String version;
}
return JAXB.unmarshal(file, Behavior.class).version;
}
StAX для повышения эффективности:
private static String readVersionEfficient(File file)
throws XMLStreamException, IOException {
XMLInputFactory inFactory = XMLInputFactory.newInstance();
XMLStreamReader xmlReader = inFactory
.createXMLStreamReader(new StreamSource(file));
try {
while (xmlReader.hasNext()) {
if (xmlReader.next() == XMLStreamConstants.START_ELEMENT) {
if (xmlReader.getLocalName().equals("behavior")) {
return xmlReader.getAttributeValue(null, "version");
} else {
throw new IOException("Invalid file");
}
}
}
throw new IOException("Invalid file");
} finally {
xmlReader.close();
}
}
Комментарии:
1. Эта версия JAXB довольно тревожна с точки зрения накладных расходов. 🙂
Ответ №3:
Вот один из них.
import javax.xml.parsers.SAXParser;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.SAXException;
import org.xml.sax.Attributes;
import javax.xml.parsers.SAXParserFactory;
/**
* Here is sample of reading attributes of a given XML element.
*/
public class SampleOfReadingAttributes {
/**
* Application entry point
* @param args command-line arguments
*/
public static void main(String[] args) {
try {
// creates and returns new instance of SAX-implementation:
SAXParserFactory factory = SAXParserFactory.newInstance();
// create SAX-parser...
SAXParser parser = factory.newSAXParser();
// .. define our handler:
SaxHandler handler = new SaxHandler();
// and parse:
parser.parse("sample.xml", handler);
} catch (Exception ex) {
ex.printStackTrace(System.out);
}
}
/**
* Our own implementation of SAX handler reading
* a purchase-order data.
*/
private static final class SaxHandler extends DefaultHandler {
// we enter to element 'qName':
public void startElement(String uri, String localName,
String qName, Attributes attrs) throws SAXException {
if (qName.equals("behavior")) {
// get version
String version = attrs.getValue("version");
System.out.println("Version is " version );
}
}
}
}
Комментарии:
1. Я бы использовал этот подход, если бы работал на JSE5, но javax.xml.stream API в Java 6 и JEE позволяет завершить синтаксический анализ после первого элемента, не прибегая к искусственным механизмам, таким как выдача исключения.
2. Боже, это сложно. Создание SAXParserFactory, SAXParser и пользовательского SaxHandler только для выполнения «//behavior» — это большая работа.
Ответ №4:
Как уже упоминалось, вы можете использовать SAXParser.
Digester упомянул использование регулярных выражений, которые я не буду рекомендовать, поскольку это приведет к созданию кода, который трудно поддерживать: Что, если вы добавите другой атрибут версии в другой тег или другой тег поведения? Вы можете с этим справиться, но это будет некрасиво.
Вы также можете использовать XPath, который является языком для запроса xml. Это то, что я бы рекомендовал.
Ответ №5:
Если все, что вам нужно, это прочитать версию, то вы можете использовать regex. Но на самом деле, я думаю, вам нужен apache digester
Комментарии:
1. XML regext = flame bait 🙂 Но я согласен с вашей рекомендацией apache digester.
Ответ №6:
Конфигурация Apache Commons тоже хороша. На нем основан Commons Digester.