Получение дочерних узлов XML, имеющих атрибуты - Java

1

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

<doc>
    <str name="eventId">54605a22aa7d649f085242e3</str>
    <arr name="toolLogExt">
      <str>.xls.lck</str>
      <str>.xls.lck</str>
      <str>.xls.lck</str>
    </arr>
    <arr name="messageTech">
      <str>Java run-time error</str>
      <str>Java run-time error</str>
      <str>Java run-time error</str>
    </arr>
    <arr name="messageId">
      <str>546066238d194b463e365194</str>
      <str>546090b48d194b463e365196</str>
      <str>546090f78d194b463e365198</str>
    </arr>
    <arr name="eventType">
      <str>Run-time error</str>
    </arr>
    <str name="type">acme</str>
    <arr name="messageSolution">
      <str>XXXXX</str>
      <str>YYYYY</str>
      <str>ZZZZZ</str>
    </arr>
    <arr name="toolID">
      <str>54605d7d8d194b463e36517e</str>
      <str>54605d7d8d194b463e36517e</str>
      <str>54605d7d8d194b463e36517e</str>
    </arr>
</doc>

Я прочитал много сообщений о Stack-Overflow, но я не нашел такого формата XML. Один из регулярных способов - сделать отдельную строковую обработку после получения каждого узла с соответствующими атрибутами и поддерживать счетчик для последующего построения Document Model. Однако существует ли прямой метод получения всех полей?

Edit1 Мой подход до сих пор....

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ParseSAX extends DefaultHandler {
    List<String> errorsLister;
    String inpXMLFileName;
    public ParseSAX(String xmlFileName) {
        this.inpXMLFileName = xmlFileName;
        errorsLister = new ArrayList<String>();
        parseDocument();
    }
    private void parseDocument() {
        // parse
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            SAXParser parser = factory.newSAXParser();
            parser.parse(inpXMLFileName, this);
        } catch (ParserConfigurationException e) {
            System.out.println("ParserConfig error");
        } catch (SAXException e) {
            System.out.println("SAXException : xml not well formed");
        } catch (IOException e) {
            System.out.println("IO error");
        }
    }

    @Override
    public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {

        if (elementName.equalsIgnoreCase("str")) {
            String temp = (attributes.getValue("eventId"));
            // This would give me the event ID
            // Further usage
        }
        // if current element is publisher
        if (elementName.equalsIgnoreCase("arr")) {
           String temp = attributes.getValue("messageTech");
        }
    }
    @Override
    public void endElement(String s, String s1, String element) throws SAXException {
        // Can't seem to figure out what to do here!!!
    }

    public static void main(String[] args) {
        new ParseSAX("..//input2.xml");

        // To individually get field values having attribute names
        // I know we can do this .... 
        /**
        try {
            DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = domFactory.newDocumentBuilder();
            Document dDoc;
            dDoc = builder.parse("..//input2.xml");
            XPath xPath = XPathFactory.newInstance().newXPath();
            String string = (String) xPath.evaluate("/response/result[@name='response']/doc/arr[@name='messageId']/str", dDoc, XPathConstants.STRING);
        } catch (SAXException | IOException | XPathExpressionException | ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        **/
    }
}
  • 0
    Что вы подразумеваете под «именем поля»? что ты уже испробовал? Непонятно, в чем проблема - достаточно просто получить значения атрибутов и достаточно просто получить текстовое значение элемента ...
  • 0
    Допустим, я выбираю узел с <arr> и атрибут с [@name='toolLogExt']. name = 'toolLogExt']. Как я могу получить все дочерние узлы, принадлежащие этому узлу, поскольку все они имеют поле <arr>? Я публикую свои фрагменты кода до сих пор в редактировании ..
Показать ещё 5 комментариев
Теги:
parsing

1 ответ

2
Лучший ответ

Вы можете читать элементы внутри любого тега XML, используя функцию ниже.

public class XmlFileReader{
    public NodeList readXML(String filePath, String tagName, String subTagName, String tagAttr) {
        try {
            // Get XML file object.
            File fXmlFile = new File(filePath);

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);

            doc.getDocumentElement().normalize();

            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

            NodeList nodeList = doc.getElementsByTagName(tagName);

            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) node;
                    if (element.getAttribute("name").equalsIgnoreCase(tagAttr)) {
                        NodeList elementsByTagName = element.getElementsByTagName(subTagName);
                        return elementsByTagName ;
                    }
                }
            }
        } catch (Exception e) {
            StringWriter stack = new StringWriter();
            e.printStackTrace(new PrintWriter(stack));
            LogManager.fatal(stack.toString(), ReadTemplate.class.getName());
        }
        return elementsByTagName;
    }
}

Вызов функции:

XmlFileReader xmlFileReader = new XmlFileReader();
NodeList toolLogExtChilds = xmlFileReader.readXML("Path to XML file",
                "arr", "str", "toolLogExt");
  • 0
    Спасибо за помощь! Я пробую ваше решение.
  • 0
    Получаете ли вы решение с ответом выше?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню