0

Как извлечь значение элемента XML с помощью Java?

24

Здравствуйте! Я новичок в 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 ответ(ов)

0

Если вам нужно извлечь только одно (первое) значение из 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 более универсально и позволяет избежать ошибок, которые могут возникнуть при манипуляциях со строками.

0

Если ваш 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. Если у вас есть дополнительные вопросы, не стесняйтесь спрашивать!

0

Следующие ссылки могут быть полезны:

Надеюсь, это поможет вам разобраться с вашим вопросом!

0

Вы можете создать класс, который наследует 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-файле, делая код более гибким и удобным для расширения.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь