2013-02-22 100 views
1

我的程序的概念是解析可以描述XML流内一组类的XML文件。每个类显然可以有几个方法和几个属性。这些方法又可以有几个参数。使用SAX解析器解析嵌套的XML标记可能有重复。 Java

下面是XML文件的一个例子:

<stream> 
<class package="Mainpack" name="Person" visibility="public" alias="Aaron" type="class" spot="C"> 
    <property name="id" type="String" visibility="public"></property> 
    <property name="name" type="String" visibility="public"></property> 
    <method name="setID" return="void" visibility="public"> 
    <parameter name="name" type="string"> </parameter> 
    </method> 
    <method name="getID" return="String" visibility="public"></method> 
</class> 
</stream> 

每个元素(流,类等)具有与吸气剂,setter和一个空的构造描述了它的类。该流包含一个类的列表。类包含名称,包等的属性,以及方法和参数(它们是独立的类)的列表。我不会包含这些,因为我认为它们很简单。

这是我写的XMLHandler类:

public class XMLHandler extends DefaultHandler { 

Boolean currentElement = false; 
String currentValue = null; 

public static XMLStream xmlStream; 

    public XMLClass xmlClass = null; 
    public XMLMethod xmlMethod = null; 
    public XMLProperty xmlProperty = null; 
    public XMLParameter xmlParameter = null; 

@Override 
public void startElement(String uri, String localName, String qName, 
     Attributes attributes) throws SAXException { 
    currentElement = true; 

    switch (localName) { 
     case "stream": 
      { 
       xmlStream = new XMLStream(); 
      } 
     case "class": 
      { 
       /** Start and get attribute values */ 
       xmlClass = new XMLClass(); 
       String attr = attributes.getValue("package"); 
       xmlClass.setPackageName(attr); 
       attr = attributes.getValue("name"); 
       xmlClass.setClassName(attr); 
       attr = attributes.getValue("visibility"); 
       xmlClass.setVisibility(attr); 
       attr = attributes.getValue("alias"); 
       xmlClass.setAlias(attr); 
       attr = attributes.getValue("type"); 
       xmlClass.setType(attr); 
       attr = attributes.getValue("spot"); 
       xmlClass.setSpot(attr.charAt(0)); 
       break; 
      } 
     case "method": 
      { 
       xmlMethod = new XMLMethod(); 
       String attr = attributes.getValue("name"); 
       xmlMethod.setName(attr); 
       attr = attributes.getValue("return"); 
       xmlMethod.setReturnType(attr); 
       attr = attributes.getValue("visibility"); 
       xmlMethod.setVisibility(attr); 
       xmlClass.addMethod(xmlMethod); 
       break; 
      } 
     case "property": 
      { 
       xmlProperty = new XMLProperty(); 
       String attr = attributes.getValue("name"); 
       xmlProperty.setName(attr); 
       attr = attributes.getValue("type"); 
       xmlProperty.setType(attr); 
       attr = attributes.getValue("visibility"); 
       xmlProperty.setVisibility(attr); 
       xmlClass.addProperty(xmlProperty); 
       break; 
      } 
     case "parameter": 
      { 
       xmlParameter = new XMLParameter(); 
       String attr = attributes.getValue("name"); 
       xmlParameter.setName(attr); 
       attr = attributes.getValue("type"); 
       xmlParameter.setType(attr); 
       xmlMethod.addParameter(xmlParameter); 
       break; 
      } 
     } 
} 

/** Called when tag closing (ex:- <name>AndroidPeople</name> 
* -- </name>)*/ 
@Override 
public void endElement(String uri, String localName, String qName) 
     throws SAXException { 

    currentElement = false; 

      if (localName.equalsIgnoreCase("class")) 
       xmlStream.addClass(xmlClass); 
      else if (localName.equalsIgnoreCase("method")) 
       xmlClass.addMethod(xmlMethod); 
      else if (localName.equalsIgnoreCase("property")) 
       xmlClass.addProperty(xmlProperty); 
      else if (localName.equalsIgnoreCase("parameter")) 
       xmlMethod.addParameter(xmlParameter); 
} 

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

    if (currentElement) { 
     currentValue = new String(ch, start, length); 
     currentElement = false; 
    } 

} 

} 

我希望的逻辑是正确的。解析器在遇到流标记并设置属性时创建一个Stream实例。在遇到班级标记时,​​它也是一样。在类的结束标记上,类实例被添加到流的类列表中。对于与类有关的方法和属性以及与方法有关的参数,这种行为会重复。

我测试在Windows应用程序分析器,但你可以使用这种方法:

public static void main(String[]args) 
{ 
    try { 

     String xmlst = "<stream>\n<class package=\"Mainpack\" name=\"Person\" " 
       + "visibility=\"public\" alias=\"Aaron\" type=\"class\" spot=\"C\">\n " 
       + " <property name=\"id\" type=\"String\" visibility=\"public\"></property>\n " 
       + " <method name=\"getID\" return=\"void\" visibility=\"public\">\n\t<parameter name=\"name\" type=\"string\">" 
       + " </parameter>\n </method>\n</class>\n</stream>"; 

     SAXParserFactory spf = SAXParserFactory.newInstance(); 
     SAXParser sp = spf.newSAXParser(); 
     XMLReader xr = sp.getXMLReader(); 
     XMLHandler xh = new XMLHandler(); 

     InputSource is = new InputSource(); 
     is.setCharacterStream(new StringReader(xmlst)); 
     xr.setContentHandler(xh); 
     xr.parse(new InputSource(is.getByteStream())); 

     XMLStream xmlStream = XMLHandler.xmlStream; 

     for (int i=0; i<xmlStream.getClasses().size(); i++) 
     { 
      System.out.println("*** CLASS ***"); 
      System.out.println(xmlStream.getClasses().get(i).getClassName()); 
      System.out.println(xmlStream.getClasses().get(i).getType()); 
      for (int j=0; j<xmlStream.getClasses().get(i).getProperties().size(); j++) 
      { 
       System.out.println("*** PROP ***"); 
       System.out.println(xmlStream.getClasses().get(i).getProperties().get(j).getName()); 
       System.out.println(xmlStream.getClasses().get(i).getProperties().get(j).getType()); 
      } 
      for (int j=0; j<xmlStream.getClasses().get(i).getMethods().size(); j++) 
      { 
       System.out.println("*** METH ***"); 
       System.out.println(xmlStream.getClasses().get(i).getMethods().get(j).getName()); 
       System.out.println(xmlStream.getClasses().get(i).getMethods().get(j).getReturnType()); 
       for (int k=0; k<xmlStream.getClasses().get(i).getMethods().get(j).getParameters().size(); k++) 
       { 
        System.out.println("*** PARAMS ***"); 
        System.out.println(xmlStream.getClasses().get(i).getMethods().get(j).getParameters().get(k).getName()); 
        System.out.println(xmlStream.getClasses().get(i).getMethods().get(j).getParameters().get(k).getType()); 
       } 
      } 

     } 

    } catch (IOException ex) { 
     Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (ParserConfigurationException ex) { 
     Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (SAXException ex) { 
     Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

这条线时,该计划遇到MalformedURLException异常: “xr.parse(新的InputSource(是。 getByteStream()));”

有没有人有什么想法是什么错?

回答

2

保存XML文档.xml文件(这份厚礼说),并尝试这种方法来运行你的解析器:

XMLReader reader = XMLReaderFactory.createXMLReader(); 
XMLHandler xh = new XMLHandler(); 
reader.setContentHandler(xh); 
reader.parse(PATH_TO_FILE); 

,而不是你的代码:

SAXParserFactory spf = SAXParserFactory.newInstance(); 
SAXParser sp = spf.newSAXParser(); 
XMLReader xr = sp.getXMLReader(); 
XMLHandler xh = new XMLHandler(); 

InputSource is = new InputSource(); 
is.setCharacterStream(new StringReader(xmlst)); 
xr.setContentHandler(xh); 
xr.parse(new InputSource(is.getByteStream())); 

希望它能帮助。

+0

有一个新的错误,但它与XMLHandler有关。我会尽力修复它并回复你。 – user1028408 2013-02-22 14:21:34

+0

@ user1028408,好的,我在线 – bsiamionau 2013-02-22 14:23:29

+0

好的,我已经修复了这个程序,它完美地工作。有一个小问题,我没有在对象的构造函数中初始化列表。但是,我仍然希望使用直接输入字符串来完成此操作,而不是从XML文件进行解析。你知不知道怎么? – user1028408 2013-02-23 11:07:20