Java 使用SAX解析器遍历xml文档并以所需格式打印输出

Java 使用SAX解析器遍历xml文档并以所需格式打印输出,java,xml,sax,Java,Xml,Sax,我正在尝试解析附加的xml(请查找附件)文件。 xml文档如下所示。请检查附件1和2 为了解析这个xml,我使用了SAX解析器。程序如下 package com.dom; import java.io.File; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import javax.xml.parsers.ParserConfigurationException;

我正在尝试解析附加的xml(请查找附件)文件。 xml文档如下所示。请检查附件1和2

为了解析这个xml,我使用了SAX解析器。程序如下

package com.dom;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

public class DemoXML {
    File file;
    SAXParserFactory factory;
    SAXParser saxParser;
    UserHandler handler;

    public void loadXML()
    {
        file = new File("E:/fifthWorkbenchProjects/XMLUtility/src/input/FIXBOND.xml");
        System.out.println(file.exists());
    }
    public void readXML()
    {
        factory = SAXParserFactory.newInstance();

            try {
                saxParser = factory.newSAXParser();
                handler = new UserHandler();
                try {
                    saxParser.parse(file,handler);
                } catch (IOException e) {

                    e.printStackTrace();
                }


            } catch (ParserConfigurationException e) {

                e.printStackTrace();
            } catch (SAXException e) {

                e.printStackTrace();
            }


    }
public static void main(String args[])
{
    DemoXML ob = new DemoXML();
    ob.loadXML();
    ob.readXML();
}
}

 class UserHandler extends DefaultHandler
{
     Hashtable tags;
     @Override
    public void startDocument()
    {
        System.out.println("Document started");
        tags = new Hashtable();
    }
     @Override
     public void endDocument()
     {
         System.out.println("Documents ended"); 
     }

     @Override
     public void startElement(String namespaceURI,String localName,String qname,Attributes atts) throws SAXException
     {
        // System.out.println("Element started");
        // if(qname.equals("Currency"))
        System.out.print(qname+"-->");

     }

     @Override
     public void endElement(String uri,String localName, String qname)
     {

     }
     @Override
     public void characters(char[] ch, int start, int length)
     {
         String str =  new String(ch,start,length);
         System.out.println(str);
         System.out.println();
     }

}
我以下面的方式得到输出。 真的 文件开始 FIGOVcorpagnity-->仪器说明-->仪器类型-->FI GOVcorpagnity

指令子类型-->固定绑定

仪器名称-->QUEENSNR 0%2016年6月7日

仪表说明-->皇后区0%2016年6月7日

货币-->英镑

仪表状态-->活动

数量输出-->48384375

AmtOutstandingDate-->2012-06-27T00:00:00.000

原则更改-->N

国家风险-->GB

仪表完整性-->50

资本排名-->1

统计数据-->发布日期-->2012-06-27T00:00:00.000

原始金额-->48384375

PrivatePlacementFlag-->Y

最小面额-->1000

最小增量-->0.01

以此类推……我可以访问所有节点,但观察到树中第一个元素的一点,完整的元素地址如下所示 FIGOVcorpagnity-->仪器说明-->仪器类型-->FI GOVcorpagnity

然后,对于树中的其余元素,它打印标记名和相应的值,如 指令子类型-->固定绑定

仪器名称-->QUEENSNR 0%2016年6月7日

仪表说明-->皇后区0%2016年6月7日

货币-->英镑

仪表状态-->活动

数量输出-->48384375

等等

在这里,我的要求是,我想打印这些元素,并以完整的层次结构方式作为第一个元素


怎么办

类UserHandler扩展了DefaultHandler { 列出li_元素、li_值

 LinkedHashMap<List<String>,List<String>> hm; 
 boolean endElementFlag;

 @Override
public void startDocument()
{
    System.out.println("Document started");
    li_elements = new ArrayList<String>();
    li_values=new ArrayList<String>();
}
 @Override
 public void endDocument()
 {
     System.out.println("Documents ended"+hm.size()); 
     for(Map.Entry m:hm.entrySet())
     {
         System.out.println(m.getKey()+""+m.getValue());
     }

 }

 @Override
 public void startElement(String namespaceURI,String localName,String qname,Attributes atts) throws SAXException
 {

    li_elements.add(qname);

    //System.out.println("Element Started");
    //System.out.println(qname+" added in element list");   
 }
 @Override
 public void endElement(String uri,String localName, String qname)
 {

     if(!li_values.isEmpty())
     {
     System.out.println("Element address list:-"+li_elements+"and Corresponding Value:-"+li_values);

     System.out.println();
     }

         li_elements.remove(li_elements.size()-1);
         li_values.clear();

 }
 @Override
 public void characters(char[] ch, int start, int length)
 {

    String str =  new String(ch,start,length);
    li_values.add(str);
 }  
LinkedHashMap-hm;
布尔endElementFlag;
@凌驾
公开作废开始文件()
{
System.out.println(“文件启动”);
li_elements=new ArrayList();
li_值=新的ArrayList();
}
@凌驾
公共文件()
{
System.out.println(“文档结束”+hm.size());
对于(Map.Entry m:hm.entrySet())
{
System.out.println(m.getKey()+“”+m.getValue());
}
}
@凌驾
public void startElement(字符串namespaceURI、字符串localName、字符串qname、属性atts)引发异常
{
li_元素。添加(qname);
//System.out.println(“元素已启动”);
//System.out.println(qname+“添加到元素列表中”);
}
@凌驾
公共void endElement(字符串uri、字符串localName、字符串qname)
{
如果(!li_values.isEmpty())
{
System.out.println(“元素地址列表:-“+li_元素+”和相应的值:-“+li_值”);
System.out.println();
}
移除(li_elements.size()-1);
li_值。清除();
}
@凌驾
公共无效字符(字符[]ch,整数开始,整数长度)
{
String str=新字符串(ch、start、length);
li_值。添加(str);
}  
}


我期待着这样的事情。这将以我希望的格式打印输出

这段代码最终会出现在NPE中。
hm
填充在哪里?在上面的示例中,我没有填充hm,它可以在endElement方法中完成。相反,我只是做了