Как извлечь значение элемента XML с помощью Java?
Здравствуйте! Я новичок в XML и мне нужно прочитать следующий XML-файл на основе имени запроса. Пожалуйста, помогите мне с тем, как это сделать на языке Java.
Вот сам XML:
<?xml version="1.0"?>
<config>
<Request name="ValidateEmailRequest">
<requestqueue>emailrequest</requestqueue>
<responsequeue>emailresponse</responsequeue>
</Request>
<Request name="CleanEmail">
<requestqueue>Cleanrequest</requestqueue>
<responsequeue>Cleanresponse</responsequeue>
</Request>
</config>
Я хотел бы получить данные, например, для запроса с именем "ValidateEmailRequest". Как правильно организовать код для чтения этих данных в Java? Заранее спасибо за помощь!
4 ответ(ов)
Если вам нужно извлечь только одно (первое) значение из XML, можно использовать следующий метод:
public static String getTagValue(String xml, String tagName){
return xml.split("<"+tagName+">")[1].split("</"+tagName+">")[0];
}
Однако, если вы планируете парсить весь XML-документ, я рекомендую использовать библиотеку JSoup, которая упрощает работу с XML и HTML. Например, вы можете использовать следующий код:
Document doc = Jsoup.parse(xml, "", Parser.xmlParser());
for (Element e : doc.select("Request")) {
System.out.println(e);
}
Использование JSoup более универсально и позволяет избежать ошибок, которые могут возникнуть при манипуляциях со строками.
Если ваш XML хорошо сформирован, его можно преобразовать в объект типа Document. Затем, используя XPath, вы сможете получать элементы XML.
Вот пример:
String xml = "<stackusers><name>Yash</name><age>30</age></stackusers>";
Сначала создаем документ из XML-строки и находим элементы с использованием XPath.
Document doc = getDocument(xml, true);
public static Document getDocument(String xmlData, boolean isXMLData) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
dbFactory.setIgnoringComments(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc;
if (isXMLData) {
InputSource ips = new org.xml.sax.InputSource(new StringReader(xmlData));
doc = dBuilder.parse(ips);
} else {
doc = dBuilder.parse(new File(xmlData));
}
return doc;
}
Теперь вы можете использовать org.apache.xpath.XPathAPI
для получения узлов или NodeList.
System.out.println("XPathAPI:" + getNodeValue(doc, "/stackusers/age/text()"));
NodeList nodeList = getNodeList(doc, "/stackusers");
System.out.println("XPathAPI NodeList:" + getXmlContentAsString(nodeList));
System.out.println("XPathAPI NodeList:" + getXmlContentAsString(nodeList.item(0)));
public static String getNodeValue(Document doc, String xpathExpression) throws Exception {
Node node = org.apache.xpath.XPathAPI.selectSingleNode(doc, xpathExpression);
String nodeValue = node.getNodeValue();
return nodeValue;
}
public static NodeList getNodeList(Document doc, String xpathExpression) throws Exception {
NodeList result = org.apache.xpath.XPathAPI.selectNodeList(doc, xpathExpression);
return result;
}
Также можно использовать javax.xml.xpath.XPathFactory
:
System.out.println("javax.xml.xpath.XPathFactory:" + getXPathFactoryValue(doc, "/stackusers/age"));
static XPath xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
public static String getXPathFactoryValue(Document doc, String xpathExpression) throws XPathExpressionException, TransformerException, IOException {
Node node = (Node) xpath.evaluate(xpathExpression, doc, XPathConstants.NODE);
String nodeStr = getXmlContentAsString(node);
return nodeStr;
}
Еще один вариант — получить значение элемента напрямую:
System.out.println("DocumentElementText:" + getDocumentElementText(doc, "age"));
public static String getDocumentElementText(Document doc, String elementName) {
return doc.getElementsByTagName(elementName).item(0).getTextContent();
}
Для получения значения между двумя строками вы можете использовать:
String nodeValue = org.apache.commons.lang.StringUtils.substringBetween(xml, "<age>", "</age>");
System.out.println("StringUtils.substringBetween():" + nodeValue);
Полный пример:
public static void main(String[] args) throws Exception {
String xml = "<stackusers><name>Yash</name><age>30</age></stackusers>";
Document doc = getDocument(xml, true);
String nodeValue = org.apache.commons.lang.StringUtils.substringBetween(xml, "<age>", "</age>");
System.out.println("StringUtils.substringBetween():" + nodeValue);
System.out.println("DocumentElementText:" + getDocumentElementText(doc, "age"));
System.out.println("javax.xml.xpath.XPathFactory:" + getXPathFactoryValue(doc, "/stackusers/age"));
System.out.println("XPathAPI:" + getNodeValue(doc, "/stackusers/age/text()"));
NodeList nodeList = getNodeList(doc, "/stackusers");
System.out.println("XPathAPI NodeList:" + getXmlContentAsString(nodeList));
System.out.println("XPathAPI NodeList:" + getXmlContentAsString(nodeList.item(0)));
}
public static String getXmlContentAsString(Node node) throws TransformerException, IOException {
StringBuilder stringBuilder = new StringBuilder();
NodeList childNodes = node.getChildNodes();
int length = childNodes.getLength();
for (int i = 0; i < length; i++) {
stringBuilder.append(toString(childNodes.item(i), true));
}
return stringBuilder.toString();
}
Вывод программы будет следующим:
StringUtils.substringBetween():30
DocumentElementText:30
javax.xml.xpath.XPathFactory:30
XPathAPI:30
XPathAPI NodeList:<stackusers>
<name>Yash</name>
<age>30</age>
</stackusers>
XPathAPI NodeList:<name>Yash</name><age>30</age>
Это хороший способ работы с XML в Java. Если у вас есть дополнительные вопросы, не стесняйтесь спрашивать!
Следующие ссылки могут быть полезны:
- Java XML Tutorial от labe.felk.cvut.cz
- Обучающий материал по Java от developerlife.com
- Примеры кода по Java от java-samples.com
Надеюсь, это поможет вам разобраться с вашим вопросом!
Вы можете создать класс, который наследует org.xml.sax.helpers.DefaultHandler
, и вызывать методы:
start_<tag_name>(Attributes attrs);
и
end_<tag_name>();
Например, для тега request_queue
это будет выглядеть так:
start_request_queue(attrs);
Затем вы можете наследовать этот класс и реализовать парсеры для XML конфигурационных файлов, которые вам нужны. Пример реализации может выглядеть следующим образом:
public void startElement(String uri, String name, String qname,
org.xml.sax.Attributes attrs)
throws org.xml.sax.SAXException {
Class[] args = new Class[2];
args[0] = uri.getClass();
args[1] = org.xml.sax.Attributes.class;
try {
String mname = name.replace("-", "");
java.lang.reflect.Method m =
getClass().getDeclaredMethod("start" + mname, args);
m.invoke(this, new Object[] { uri, (org.xml.sax.Attributes)attrs });
}
catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
catch (java.lang.reflect.InvocationTargetException e) {
org.xml.sax.SAXException se =
new org.xml.sax.SAXException(e.getTargetException());
se.setStackTrace(e.getTargetException().getStackTrace());
}
}
И в конкретном парсере конфигурации вы можете реализовать метод start_Request
.
public void start_Request(String uri, org.xml.sax.Attributes attrs) {
// убедитесь, что вы правильно считываете атрибуты
System.err.println("Request, name=" + attrs.getValue(0));
}
Таким образом, вы можете динамически вызывать методы для обработки начала тегов в вашем XML-файле, делая код более гибким и удобным для расширения.
Инициализация ArrayList в одну строчку
Почему нет ConcurrentHashSet, если есть ConcurrentHashMap?
Что такое «сырые типы» и почему их не следует использовать?
Создание репозитория Spring без сущности
Как сгенерировать уникальный хеш-код для строкового ввода в Android?