2013-02-22 1 views
1

Концепция моей программы заключается в анализе XML-файла, который может описывать набор классов в потоке XML. Очевидно, что каждый класс имеет несколько методов и несколько свойств. Методы, в свою очередь, также могут иметь несколько параметров.Анализ вложенных тегов XML с возможными дубликатами с использованием SAX Parser. 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> 

Каждый элемент (поток, класс и т.д. ...) есть класс, который описывает его с добытчиками, инкубационных и пустой конструктор. Поток содержит список классов. Классы содержат атрибуты для имени, пакета и т. Д. И списки для методов и параметров (которые являются отдельными классами сами по себе). Я не буду включать их, потому что я думаю, что они просты.

Это класс 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, когда он встречает тег потока и устанавливает атрибуты. При встрече с тегом класса он делает то же самое. В закрывающем теге для класса экземпляр класса добавляется в список классов потока. Такое поведение повторяется в отношении методов и свойств по отношению к классам и параметров по отношению к методам.

Я тестирую анализатор в окна приложения, но вы можете с помощью этого метода:

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 документа (сказал Nuff) и попробовать этот подход, чтобы запустить анализатор:

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

+0

@ user1028408, хорошо, я онлайн – bsiamionau

+0

Хорошо, я исправил программу, и она отлично работает. Была небольшая проблема, когда я не инициализировал списки в конструкторах объектов. Но я все же хотел бы сделать это с помощью прямой строки ввода, а не из синтаксиса XML-файла. Ты знаешь как? – user1028408