Концепция моей программы заключается в анализе XML-файла, который может описывать набор классов в потоке XML. Очевидно, что каждый класс имеет несколько методов и несколько свойств. Методы, в свою очередь, также могут иметь несколько параметров.Анализ вложенных тегов XML с возможными дубликатами с использованием SAX Parser. 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>
Каждый элемент (поток, класс и т.д. ...) есть класс, который описывает его с добытчиками, инкубационных и пустой конструктор. Поток содержит список классов. Классы содержат атрибуты для имени, пакета и т. Д. И списки для методов и параметров (которые являются отдельными классами сами по себе). Я не буду включать их, потому что я думаю, что они просты.
Это класс 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, когда он встречает тег потока и устанавливает атрибуты. При встрече с тегом класса он делает то же самое. В закрывающем теге для класса экземпляр класса добавляется в список классов потока. Такое поведение повторяется в отношении методов и свойств по отношению к классам и параметров по отношению к методам.
Я тестирую анализатор в окна приложения, но вы можете с помощью этого метода:
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
@ user1028408, хорошо, я онлайн – bsiamionau
Хорошо, я исправил программу, и она отлично работает. Была небольшая проблема, когда я не инициализировал списки в конструкторах объектов. Но я все же хотел бы сделать это с помощью прямой строки ввода, а не из синтаксиса XML-файла. Ты знаешь как? – user1028408