在java中使用反射api解析xml

问题描述 投票:0回答:2

这是我的 XML 文件。

<customer>
  <Field Number = '1' Value = '3'>
    <Name>customer1</Name>
    <Length>2</Length>
    <Type>regular</Type>
    <Method Number = '1'>pay through cash</Method>
    <Method Number = '2'>pay through card</Method>
  </Field>
  <Field Number = '2'>
    <Name>customer2</Name>
    <Length>2</Length>
    <Type>rare</Type>
  </Field>
  <Field Number = '3'>
    <Name>customer3</Name>
    <Length>4</Length>
    <Type>regular</Type>
  </Field>
</customer>

我应该使用java语言中的任何解析器来解析这个文件。
但是我的java源代码不应该包含xml文件的任何组件,例如

node.getAttributes().getNamedItem("Name").getNodeValue();
在上面的说明中我使用了“名称”,但我不应该使用它。
哪种解析器对于这种情况是有效的。甚至欢迎代码片段。
我必须能够即时解析这个文件并将标签内容用作类成员以及 setter 和 getter 方法。所以我使用了反射 api。

java reflection xml-parsing
2个回答
1
投票

我假设你已经有了相应的类型。 您可能需要稍微改变它们,因为如果不具体(您试图避免),您将很难将具有相同名称的 xml 元素分配给字段(可能是集合)。例如,您必须将元素称为 因此,属于集合的每个元素都应作为集合(可以包含任何元素)或列表(可以包含同类元素)来处理

<ExampleSet>
  <ExampleList>
    <ExampleType>example1</ExampleType>
    <ExampleType>example2</ExampleType>
  </ExampleList>
  <OtherExampleType>example3</OtherExampleType>
</ExampleSet>

您现在可以使用相应的接口标记每种类型(例如 XmlSet、XmlList、XmlType)。 现在您可以解析它们,知道它们是否是由其他类型组成的集合,如果它们是列表,则它们是类型的集合,或者它们只是一个类型。现在,您可以根据通过反射确定的字段类型,使用反射将 XmlType 的值或属性分配给 String、int、long 或任何您需要的值。

下面是一个非常抽象的想法,如果您需要更多细节,请告诉我:

void readXml(Xml xml) {
  if (xml instanceof XmlSet) readSet(xml);
  else if (xml instanceof XmlList) readList(xml);
  else if (xml instanceof XmlType) readType(xml);
}

void readSet(Xml xml) {
  /*here you loop through the elements of set and call readXml(child)*/
}

void readList(Xml xml) {
  /*here you loop through the elements of list and call readXml(child).*/
}

void readType(Xml xml) {
  /* Here you use reflection to populate the value of elements with the corresponding java types */
}

0
投票

import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Control;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static org.w3c.dom.Node.TEXT_NODE;
public class XMLJavaFXLoader {

    public double minWidth;
    public int sum  = 0;
    public double minHeight;
    public String stageTitle;
    public Scene scene;
    Pane contain;
    Document doc;
    XPath path;
    Stage  stage;
    Element root;
    Controller controller;
    public XMLJavaFXLoader(String s) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        File file = new File(s);
        doc = db.parse(file);

        XPathFactory xpf = XPathFactory.newInstance();
        path = xpf.newXPath();
        setUpContainer();
    }

    void setScene() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {

        scene = new Scene(contain);
        setUpStage();
    }
    void setUpStage() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        stage = new Stage();
        stage.setTitle(root.getAttribute("title"));
        stageTitle = stage.getTitle();
        stage.setScene(scene);
        pop();
    }

    void setUpContainer() throws XPathExpressionException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        XPathExpression ex = path.compile("//Stage");
        root = (Element) ex.evaluate(doc, XPathConstants.NODE);
        NodeList temp = root.getChildNodes();
        System.out.println(root.getTagName());
        Node newOne = temp.item(0);
        String cur1 = String.valueOf(newOne.getNodeType());
        int count = 0;
        while(cur1.equals( String.valueOf(TEXT_NODE)))
        {
            newOne = newOne.getNextSibling();
            cur1 = String.valueOf(newOne.getNodeType());
        }
        Element newOne2 = (Element) newOne;
        String tag = newOne2.getTagName();
        String name = "javafx.scene.layout."+ newOne2.getTagName();
        Class<Pane> control = (Class<Pane>) Class.forName(name);
        contain = control.newInstance();
        setScene();
    }

    void child(Element cur1,Pane box) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        int x = 0;
        NodeList list = cur1.getChildNodes();
        for(int i = 0; i <list.getLength(); i = i + x)
        {
            Node cur2 =  list.item(i);
            while(cur2.getNodeType()== TEXT_NODE)
            {
                cur2 = cur2.getNextSibling();
                x++;
            }
            Element cur3 = (Element)cur2;
            NamedNodeMap par =  cur2.getAttributes();

            if(cur2.getNodeName().equals("TextField")|| cur2.getNodeName().equals("Label")||
                    cur2.getNodeName().equals("Button") ) {
                String name = "javafx.scene.control." + cur2.getNodeName();
                Class<Control> control = (Class<Control>) Class.forName(name);
                Constructor constr = control.getConstructor(String.class);

                controller = new Controller();
                Control con = (Control) constr.newInstance(cur3.getAttribute("text"));
                if (par.getLength() == 2) {
                    con.setId(cur3.getAttribute("id"));
                } else if (par.getLength() == 3) {
                    con.setId(cur3.getAttribute("id"));
                    String name1 = String.valueOf(cur3.getAttribute("onAction"));
                    Method [] listM = controller.getClass().getMethods();
                    Class clazz2 = controller.getClass();

                    if (String.valueOf(con.getClass()).equals("Button")) {
                        Button b1 = (Button) con;
                        b1.setOnAction((event) ->
                                {
                                    Method exe = null;
                                    try {
                                        exe = clazz2.getDeclaredMethod(name1, ActionEvent.class);
                                    } catch (NoSuchMethodException e) {
                                        throw new RuntimeException(e);
                                    }
                                    try {
                                        exe.invoke(event);
                                    } catch (IllegalAccessException e) {
                                        throw new RuntimeException(e);
                                    } catch (InvocationTargetException e) {
                                        throw new RuntimeException(e);
                                    }
                                }
                        );
                    }
                }
                box.getChildren().add(con);
                sum++;
            }
            else
            {
                String name = "javafx.scene.layout." + cur2.getNodeName();
                Pane newBox = (Pane) Class.forName(name).newInstance();

                child(cur3,newBox);
                box.getChildren().add(newBox);
                System.out.println();
                sum++;
            }
        }
    }
    void pop() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        NodeList list = root.getChildNodes();
        int count = 0;
        Node temp3 =  list.item(0);

        Node cur1 =  temp3;
        while(count <= list.getLength())
        {
            while(cur1.getNodeType()== TEXT_NODE)
            {
               cur1 = (Element) cur1.getNextSibling();
               count++;
            }
            String name = "javafx.scene.layout."+ cur1.getNodeName();
            Class<Pane> control = (Class<Pane>) Class.forName(name);
            Pane temp = control.newInstance();
            child((Element) cur1,temp);
            count++;
            count = count + sum;
            sum = 0;
            contain.getChildren().add(temp);
        }
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.