我的程序的概念是解析一个 XML 文件,该文件可以描述 XML 流中的一组类。每个类显然可以有几个方法和几个属性。反过来,这些方法也可以有几个参数。
以下是 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>
每个元素(流、类等)都有一个用 getter、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(new inputSource(is.getByteStream()));”
有人对出了什么问题有任何想法吗?