【问题标题】:Get all the tags and values from XML using SAX parser in java在 java 中使用 SAX 解析器从 XML 中获取所有标签和值
【发布时间】:2015-03-26 12:16:12
【问题描述】:

我正在尝试使用 SAX 解析 xml。我希望以嵌套方式从 xml 中获取所有标签及其值。 SAX 解析器是否可能。谁能给我一个例子。 (我认为 SAX 比 w3 文档生成器更高效,所以我选择了它。而且我想知道我在正确的道路上的天气) 我正在附加我的 java 程序

class MySAXApp extends DefaultHandler
{
    public MySAXApp ()
    {
        super();
    }
    public void startDocument ()
    {
        System.out.println("Start document");
    }
    public void endDocument ()
    {
        System.out.println("End document");
    }


    public void startElement (String uri, String name,
            String qName, Attributes atts)
    {
        System.out.println(atts.getLength());
        if ("".equals (uri))
            System.out.println("Start element: " + qName);
        else
            System.out.println("Start element: {" + uri + "}" + name);
    }

}

这是我的 XML。 这是一个有效的xml吗?这样写xml有没有错误

<?xml version="1.0" encoding="utf-8"?>
<CustomerReport xsi:schemaLocation="Customer.xsd">
    <Customer>
        <CustomerName>str1234</CustomerName>
        <CustomerStatus>str1234</CustomerStatus>
        <PurchaceOrders>
            <PurchaceOrder>
                <PurchaceOrderName>str1234</PurchaceOrderName>
            </PurchaceOrder>
        </PurchaceOrders>
    </Customer>
</CustomerReport>

我是 XML 新手。有人可以帮我解决这个问题吗

【问题讨论】:

  • 是的,这是可能的,但是您必须使用 SAX 解析器自己编写和处理数据结构(这意味着 SAX 解析器不会自己返回您期望的数据结构)。 SAX 解析器基本上在找到标记时调用您定义的方法。找到该标签后,您可以做自己想做的事情。

标签: java xml sax


【解决方案1】:

当您说 SAX“更高效”时,您的实际意思是 SAX 解析器只做最少的工作,而将大部分工作留给应用程序。这意味着您(应用程序编写者)有更多的代码要编写,而且正如您所发现的那样,这是相当棘手的代码。因为编写 XML 解析器的人是比您更有经验的 Java 编码人员,所以您在代码中做的工作越多,在解析器中做的越少,整个应用程序的效率就会越低。因此,鉴于您的经验水平,我的建议是使用一种解析方法,让库尽可能多地完成工作。我建议使用 JDOM2。

【讨论】:

  • 你好,有没有库可以从xml生成xsd。因为,在我们的用例中,他们没有提前提供 xsd。
  • 这似乎是一个完全不相关的问题。在新线程中提问。
【解决方案2】:

您发布的 XML 中唯一的属性是带有 xsi 前缀的属性。其余的属性长度应为 0。

属性是标签内的键值对。您的大部分 xml 内容都在元素内部。

SAX(或 STAX)相对于 JDOM 之类的效率优势是由于 sax 解析器不会将其读取的所有数据都保存在内存中。如果您使用 contentHandler 来检索数据并在读取数据时将其保存,那么您的程序就不必消耗那么多内存。

阅读this tutorial 或this Javaworld article。您需要实现字符方法才能获取任何元素文本。两篇链接的文章都有很好的例子来说明如何实现您的字符方法,以便您可以检索元素文本。

如果您在 Google 周围搜索 (bad example) 或在 stackoverflow (bad example here) 上搜索,您可能会找到很多不好的示例,但链接文章中的示例实现是正确的,因为它们缓冲 characters 方法的输出,直到找到所有字符:

解析器不需要一次返回任何特定数量的字符。解析器一次可以返回从单个字符到数千个字符的任何内容,并且仍然是符合标准的实现。因此,如果您的应用程序需要处理它看到的字符,明智的做法是让 characters() 方法将字符累积在 java.lang.StringBuffer 中,并仅在您确定所有字符都已找到时才对它们进行操作。

这里是 JavaWorld 文章的 hello world 示例中的 ContentHandler 更改为使用您的 xml:

import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.io.*;
public class Example2 extends DefaultHandler {
   // Local variables to store data
   // found in the XML document
   public  String  name       = "";
   public  String  status   = "";
   public String orderName = ""
   // Buffer for collecting data from // the "characters" SAX event.
   private CharArrayWriter contents = new CharArrayWriter();
   // Override methods of the DefaultHandler class
   // to gain notification of SAX Events.
   //
        // See org.xml.sax.ContentHandler for all available events.
   //
   public void startElement( String namespaceURI,
              String localName,
              String qName,
              Attributes attr ) throws SAXException {
      contents.reset();
   }
   public void endElement( String namespaceURI,
              String localName,
              String qName ) throws SAXException {
      if ( localName.equals( "CustomerName" ) ) {
         name = contents.toString();
      }
      if ( localName.equals( "CustomerStatus" ) ) {
         status = contents.toString();
      }
      if (localName.equals("PurchaceOrderName")) {
         orderName = contents.toString();
      }
   }
   public void characters( char[] ch, int start, int length )
                  throws SAXException {
      contents.write( ch, start, length );
   }
}

【讨论】:

    猜你喜欢
    • 2012-05-09
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    相关资源
    最近更新 更多