有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

获取具有Java属性的XML节点的子节点

我有一个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>

我读过很多关于堆栈溢出的帖子,但我还没有找到像这样的XML格式。其中一种常规方法是在获取每个节点及其各自的属性后进行单独的字符串处理,并维护一个计数,以便稍后构建文档模型。然而,有没有直接的方法来获取所有字段

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();
        }
        **/
    }
}

共 (1) 个答案

  1. # 1 楼答案

    您可以使用下面的函数读取任何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");