如何在不指定名称的情况下通常在Java中获取XML属性?

时间:2015-12-18 10:50:43

标签: java xml

我试图以一种通用的方式浏览XML文档,因为它对它一无所知,除了它有多少级别:

<nodelevel1>
    <nodelevel2 attribute="xyz">
    </nodelevel2>
</nodelevel1>

因此,我采用这个XML文档并以通用方式提取其中的所有信息(因此没有XPath,没有.getElementsByTagName("carname").item(0).getTextContent()等)。我这样做是为了更好地理解使用XML,而不是为了获得完美的解决方案,我意识到有更简单/更好的解决方案。这仅用于学习目的。

除了属性company="Ferrari"company="Lamborgini"等外,我能够以通用方式获取所有信息。 我不得不使用"Company: " + eElement.getAttribute("company")

那么如何在不指定节点的情况下获取节点的属性(这里是公司)?

sportscars.xml

     <?xml version="1.0"?>
     <cars>
        <supercars company="Ferrari">
           <carname type="formula one">Ferarri 101</carname>
           <carname type="sports car">Ferarri 201</carname>
           <carname type="sports car">Ferarri 301</carname>
        </supercars>
        <supercars company="Lamborgini">
           <carname>Lamborgini 001</carname>
           <carname>Lamborgini 002</carname>
           <carname>Lamborgini 003</carname>
        </supercars>
        <luxurycars company="Benteley">
           <carname>Benteley 1</carname>
           <carname>Benteley 2</carname>
           <carname>Benteley 3</carname>
        </luxurycars>
     </cars>

我的java-class QueryXMLFileDemo.java

    public class QueryXmlFileDemo {

        public static void main(String[] args) {
            try {
                File inputFile = new File("sportcars.xml");
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                Document inputDocument = dBuilder.parse(inputFile);
                inputDocument.getDocumentElement().normalize();
                Node carsNode = inputDocument.getFirstChild();
                NodeList carsNodeList = carsNode.getChildNodes();
                for (int i = 0; i < carsNodeList.getLength(); i++) {
                    Node carTypes = carsNodeList.item(i);

                    String attributeName = carsNodeList.item(i).getNodeName();
                    System.out.println("Attribute Name: " + attributeName);     

                    // hides the #text-entries
                    if (Node.ELEMENT_NODE != carTypes.getNodeType()) {
                        continue;
                    }
                    if (carTypes.getNodeType() == Node.ELEMENT_NODE) {
                        Element eElement = (Element) carTypes;
                        // Line I want to do generically without specifying the attributes name
                        System.out.println("Company: " + eElement.getAttribute("company"));
                    }
                    System.out.println("CarType: " + carTypes.getNodeName());
                    NodeList carNamesList = carTypes.getChildNodes();
                    for (int j = 0; j < carNamesList.getLength(); j++) {
                        Node carNameNode = carNamesList.item(j);
                        if (Node.ELEMENT_NODE != carNameNode.getNodeType()) {
                            continue;
                        }
                        System.out.println("Car: " + carNameNode.getTextContent());
                    }
                    System.out.println("");
                }
            } catch (Exception e) {
            }
        }
    }

输出:

Company: Ferrari
CarType: supercars
Car: Ferarri 101
Car: Ferarri 201
Car: Ferarri 301

Company: Lamborgini
CarType: supercars
Car: Lamborgini 001
Car: Lamborgini 002
Car: Lamborgini 003

Company: Benteley
CarType: luxurycars
Car: Benteley 1
Car: Benteley 2
Car: Benteley 3

2 个答案:

答案 0 :(得分:1)

迭代Element的所有属性:

NamedNodeMap attrs = element.getAttributes();
for (int i = 0; i < attrs.getLength(); i++) {
    Attr attr = (Attr)attrs.item(i);
    String name = attr.getName();
    String value = attr.getValue();
    // use here
}

答案 1 :(得分:0)

这里有一个完整的答案,有SAX(请妥善处理异常等:))

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SaxParserExample {
  public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
    SAXParserFactory spf = SAXParserFactory.newInstance();
    spf.setNamespaceAware(true);
    SAXParser saxParser = spf.newSAXParser();
    File file = new File("c:\\temp\\sportscars.xml");
    InputStream inputStream = new FileInputStream(file);
    Reader reader = new InputStreamReader(inputStream, "UTF-8");
    InputSource is = new InputSource(reader);
    is.setEncoding("UTF-8");
    saxParser.parse(is, new DefaultHandler() {
      boolean captureCarName = false;

      @Override
      public void startElement(String uri, String localName, String qName, Attributes attributes)
          throws SAXException {
        String company = attributes.getValue("company");
        if (company != null) {
          System.out.println("Company: " + company);
          System.out.println("CarType: " + localName);
        }
        if ("carname".equals(localName)) {
          captureCarName = true;
        }
      }

      @Override
      public void endElement(String uri, String localName, String qName) throws SAXException {
        if ("carname".equals(localName)) {
          captureCarName = false;
        }
      }

      @Override
      public void characters(char[] ch, int start, int length) throws SAXException {
        if (captureCarName) {
          System.out.println("Car: " + new String(ch, start, length));
        }
      }
    });
  }
}

输出:

Company: Ferrari
CarType: supercars
Car: Ferarri 101
Car: Ferarri 201
Car: Ferarri 301
Company: Lamborgini
CarType: supercars
Car: Lamborgini 001
Car: Lamborgini 002
Car: Lamborgini 003
Company: Benteley
CarType: luxurycars
Car: Benteley 1
Car: Benteley 2
Car: Benteley 3