我的程序的概念是解析可以描述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()));」
有沒有人有什麼想法是什麼錯?
有一個新的錯誤,但它與XMLHandler有關。我會盡力修復它並回復你。 – user1028408 2013-02-22 14:21:34
@ user1028408,好的,我在線 – bsiamionau 2013-02-22 14:23:29
好的,我已經修復了這個程序,它完美地工作。有一個小問題,我沒有在對象的構造函數中初始化列表。但是,我仍然希望使用直接輸入字符串來完成此操作,而不是從XML文件進行解析。你知不知道怎麼? – user1028408 2013-02-23 11:07:20