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>

各要素 (ストリーム、クラスなど) には、ゲッター、セッター、および空のコンストラクターでそれを記述するクラスがあります。ストリームには、クラスのリストが含まれています。クラスには、名前、パッケージなどの属性と、メソッドとパラメーターのリストが含まれます (これらは個別のクラスです)。これらは簡単だと思うので含めません。

これは私が書いた 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 タグに一致して属性を設定すると、Stream のインスタンスを作成します。クラスタグに会うとき、それは同じことをします。class の終了タグで、クラス インスタンスがストリームのクラス リストに追加されます。この動作は、クラスに関連するメソッドとプロパティ、およびメソッドに関連するパラメーターに関して繰り返されます。

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

「xr.parse(new inputSource(is.getByteStream()));」という行を実行すると、プログラムで MalformedURLException が発生します。

誰が何が間違っているのか考えていますか?

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 に答える