1

我的程序的概念是解析一个 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()));”

有人对出了什么问题有任何想法吗?

4

1 回答 1

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()));

希望能帮助到你。

于 2013-02-22T13:25:55.417 回答