使用SAX解析器解析嵌套的XML标记可能有重复。 Java
问题描述:
我的程序的概念是解析可以描述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()));”
有没有人有什么想法是什么错?
答
保存XML文档.xml
文件(这份厚礼说),并尝试这种方法来运行你的解析器:
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()));
希望它能帮助。
有一个新的错误,但它与XMLHandler有关。我会尽力修复它并回复你。 – user1028408 2013-02-22 14:21:34
@ user1028408,好的,我在线 – bsiamionau 2013-02-22 14:23:29
好的,我已经修复了这个程序,它完美地工作。有一个小问题,我没有在对象的构造函数中初始化列表。但是,我仍然希望使用直接输入字符串来完成此操作,而不是从XML文件进行解析。你知不知道怎么? – user1028408 2013-02-23 11:07:20