【问题标题】:Find the value of a specific attribute in an XML file in java在java中查找XML文件中特定属性的值
【发布时间】:2009-08-25 19:34:52
【问题描述】:

我只需要使用 java.xml 读取 XML 文件中单个属性的值。 XML 看起来像这样:

<behavior name="Fred" version="2.0" ....>

我只需要读出版本。有人可以指出可以告诉我如何做到这一点的资源的方向吗?

【问题讨论】:

  • 这是一个很好的例子,为什么简单的事情并不总是容易完成。尽管大多数 Java 框架都严重依赖 XML,但用于在 Java 中准确处理 XML 的工具却相当繁琐。

标签: java xml


【解决方案1】:

您不需要花哨的库——DOMXPath 的普通旧 JAXP 版本非常容易读写。无论你做什么,都不要使用正则表达式。

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;

public class GetVersion {
    public static void main(String[] args) throws Exception {
        XPath xpath = XPathFactory.newInstance().newXPath();
        Document doc = DocumentBuilderFactory.newInstance()
            .newDocumentBuilder().parse("file:////tmp/whatever.xml");
        String version = xpath.evaluate("//behavior/@version", doc);
        System.out.println(version);
    }
}

【讨论】:

    【解决方案2】:

    JAXB 为简洁起见:

      private static String readVersion(File file) {
        @XmlRootElement class Behavior {
          @XmlAttribute String version;
        }
        return JAXB.unmarshal(file, Behavior.class).version;
      }
    

    StAX 效率:

      private static String readVersionEfficient(File file)
          throws XMLStreamException, IOException {
        XMLInputFactory inFactory = XMLInputFactory.newInstance();
        XMLStreamReader xmlReader = inFactory
            .createXMLStreamReader(new StreamSource(file));
        try {
          while (xmlReader.hasNext()) {
            if (xmlReader.next() == XMLStreamConstants.START_ELEMENT) {
              if (xmlReader.getLocalName().equals("behavior")) {
                return xmlReader.getAttributeValue(null, "version");
              } else {
                throw new IOException("Invalid file");
              }
            }
          }
          throw new IOException("Invalid file");
        } finally {
          xmlReader.close();
        }
      }
    

    【讨论】:

    • 那个 JAXB 版本在开销方面相当令人不安。 :)
    【解决方案3】:

    这里是one

    import javax.xml.parsers.SAXParser;
    import org.xml.sax.helpers.DefaultHandler;
    import org.xml.sax.SAXException;
    import org.xml.sax.Attributes;
    import javax.xml.parsers.SAXParserFactory;
    
    /**
     * Here is sample of reading attributes of a given XML element.
     */
    
    public class SampleOfReadingAttributes {
        /**
         * Application entry point
         * @param args command-line arguments
         */
        public static void main(String[] args) {
            try {
                // creates and returns new instance of SAX-implementation:
                SAXParserFactory factory = SAXParserFactory.newInstance();
    
                // create SAX-parser...
                SAXParser parser = factory.newSAXParser();
                // .. define our handler:
                SaxHandler handler = new SaxHandler();
    
                // and parse:
                parser.parse("sample.xml", handler);
    
            } catch (Exception ex) {
                ex.printStackTrace(System.out);
            }
        }
    
        /**
         * Our own implementation of SAX handler reading
         * a purchase-order data.
         */
        private static final class SaxHandler extends DefaultHandler {
    
            // we enter to element 'qName':
            public void startElement(String uri, String localName,
                    String qName, Attributes attrs) throws SAXException {
    
                if (qName.equals("behavior")) {
                    // get version
                    String version = attrs.getValue("version");
    
    
                    System.out.println("Version is " + version );
    
                }
            }
        }
    }
    

    【讨论】:

    • 如果我在 JSE5 上,我会使用这种方法,但 Java 6 和 JEE 中的 javax.xml.stream API 允许您在第一个元素之后退出解析,而无需求助于抛出异常等人为机制.
    • 男孩,这很复杂。创建一个 SAXParserFactory、一个 SAXParser 和一个自定义 SaxHandler 只是为了执行“//behaviour”是很多工作。
    【解决方案4】:

    如前所述,您可以使用 SAXParser。

    Digester 提到了使用正则表达式,我不建议这样做,因为它会导致代码难以维护:如果在另一个标签或另一个行为标签中添加另一个版本属性怎么办?你可以处理它,但它不会很漂亮。

    你也可以使用XPath,这是一种查询xml的语言。这就是我的建议。

    【讨论】:

      【解决方案5】:

      如果您只需要阅读版本,那么您可以使用正则表达式。但说真的,我觉得你需要apache digester

      【讨论】:

      • XML + regext = flame bait :) 但我同意你对 apache digester 的建议。
      【解决方案6】:

      Apache Commons Configuration 也不错。 Commons Digester 就是基于它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-04
        • 1970-01-01
        • 2018-09-07
        • 1970-01-01
        • 1970-01-01
        • 2016-06-07
        • 1970-01-01
        相关资源
        最近更新 更多