【问题标题】:How to append to xml table with java?如何用java附加到xml表?
【发布时间】:2023-03-17 14:50:01
【问题描述】:

好的,所以我正在创建一个用户类,它要求输入,然后使用 java 将其存储在 XML 文件中。我想创建我认为的原始 XML 文件,但我无法弄清楚如何添加一个属性“id”比上一个用户条目多一个的新用户。

这是我目前的代码:

/*imports */

    public class CreateUser {   
        static Scanner input = new Scanner(System.in);

/* object names*/
    String name;
    String age;
    String bday;
    String gender;
    String location;
    String orientation;
    String relationship;
    String hobbies;
    String choice;
    String username;
    String password;

    public void makeUser(){

/*left out code to get user entries here 

seemed irrelevant/*

    /*checks for file if it doesn't exist then it creates it else it should append
 the user to the xml document with a id increase of one.
 The appending part I'm not sure how to do.*/
File f = new File("C:\\Users\\Steven\\Workspace\\twitter\\src\\users.xml");
            if(f.exists()) { 
                try {
                    /* need help here*/
                }
            }
            else{
                try{
                    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
                    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
                    Document users = docBuilder.newDocument();

                    Element user = users.createElement("user");
                    users.appendChild(user);

                    Attr attr = users.createAttribute("id");
                    attr.setValue("0");
                    user.setAttributeNode(attr);

                    Element dname = users.createElement("name");
                    dname.appendChild(users.createTextNode(name));
                    user.appendChild(dname);

                    Element dgender = users.createElement("gender");
                    dgender.appendChild(users.createTextNode(gender));
                    user.appendChild(dgender);

                    Element dlocation = users.createElement("location");
                    dlocation.appendChild(users.createTextNode(location);
                    user.appendChild(dlocation);

                    Element dorientation = users.createElement("orientation");
                    dorientation.appendChild(users.createTextNode(orientation));
                    user.appendChild(dorientation);

                    Element drelationship = users.createElement("relationship");
                    drelationship.appendChild(users.createTextNode(relationship));
                    drelationship.appendChild(drelationship);


                    Element dhobbies = users.createElement("hobbies");
                    dhobbies.appendChild(users.createTextNode(hobbies));
                    dhobbies.appendChild(dhobbies);

                    Element dchoice = users.createElement("choice");
                    dchoice.appendChild(users.createTextNode(choice));
                    dchoice.appendChild(dchoice);

                    Element dusername = users.createElement("username");
                    dusername.appendChild(users.createTextNode(username));
                    dusername.appendChild(dusername);

                    Element dpassword = users.createElement("password");
                    dpassword.appendChild(users.createTextNode(password));
                    dpassword.appendChild(dpassword);

                    Element dbday = users.createElement("birthday");
                    dbday.appendChild(users.createTextNode(bday));
                    dbday.appendChild(dbday);

                    Element dage = users.createElement("age");
                    dage.appendChild(users.createTextNode(age));
                    dage.appendChild(dage);

                    TransformerFactory transformerFactory = TransformerFactory.newInstance();
                    Transformer transformer = transformerFactory.newTransformer();
                    DOMSource source = new DOMSource(users);
                    StreamResult result = new StreamResult(new File("C:\\Users\\Steven\\Workspace\\twitter\\src\\users.xml"));

                    StreamResult test = new StreamResult(System.out);
                    transformer.transform(source, result);
                } catch (ParserConfigurationException pce) {
                    pce.printStackTrace();
                } catch (TransformerException tfe) {
                    tfe.printStackTrace();
                }
            }
        }

我知道它有很多代码要查看,我不想要一个精确的编码答案,但也许只是如何将属性值附加到上一个条目之后的用户。或者指向一个有用的网站的方向。任何事情真的让我有点困惑,我觉得我应该得到这么简单的东西。在此先感谢您的帮助

【问题讨论】:

  • 请举个简短的例子,看看你的 XML。谢谢

标签: java xml append


【解决方案1】:

考虑一下 SAX,与 DOM 不同,它速度快且没有大小限制。这是一个基本示例:

public static void main(String[] args) throws Exception {
    String xml = "<users><user><name>user1</name></user></users>";
    XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if (qName.equals("users")) {
                addUser();
            }
            super.endElement(uri, localName, qName);
        }

        private void addUser() throws SAXException {
            super.startElement("", "", "user", null);
            addFileld("name", "user2");
            super.endElement("", "", "user");
        }

        private void addFileld(String name, String value) throws SAXException {
            super.startElement("", "", name, null);
            super.characters(value.toCharArray(), 0, value.length());
            super.endElement("", "", name);
        }
    };
    Source src = new SAXSource(xr, new InputSource(new StringReader(xml)));
    Result res = new StreamResult(System.out);
    TransformerFactory.newInstance().newTransformer().transform(src, res);
}

输出:

   <users><user><name>user1</name></user><user><name>user2</name></user></users>

【讨论】:

    【解决方案2】:

    考虑 JAXB,下面是一个工作示例:

    static class Users {
        private List<User> user = new ArrayList<>();
    
        public List<User> getUsers() {
            return user;
        }
    
        public void setUsers(List<User> users) {
            this.user = users;
        }
    }
    
    static class User {
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    
    public static void main(String[] args) throws Exception {
        User user = new User();
        user.setName("user1");
        Users users = new Users();
        users.setUsers(Arrays.asList(user));
    
        JAXB.marshal(users, new File("users.xml"));
    
        users = JAXB.unmarshal(new File("users.xml"), Users.class);
        User user2 = new User();
        user2.setName("user2");
        users.getUsers().add(user2);
    
        JAXB.marshal(users, System.out);
    
    }
    

    【讨论】:

      【解决方案3】:

      在您的第一部分(if 块)中,我认为您可以如下以附加模式打开文件以添加 user假设 user 节点未包装在另一个节点中。强>

       StreamResult result = new StreamResult(
          new FileWriter("C:\\Users\\Steven\\Workspace\\twitter\\src\\users.xml", true));
      

      以上语句有两处变化:

      1. 使用FileWriter 代替File
      2. 使用第二个参数true,以append 模式打开文件。

      编辑:要获得最大现有ID,您需要读取文件并查找ID标签,如下所示:

        File xmlFile = new File("C:\\Users\\Steven\\Workspace\\twitter\\src\\users.xml");
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(xmlFile);
        doc.getDocumentElement().normalize();
        NodeList nList = doc.getElementsByTagName("userId");//use the id tag name
        int maxId = 0;
        for(Node node: nList){
            if(Integer.parseInt(node.getTextContent()) > maxId ){
              maxId = Integer.parseInt(node.getTextContent());
            }
        }
        int newId = maxId +1; //use this ID
        xmlFile.close();//close the file
      

      【讨论】:

      • 所以第一个 If 只是检查文件是否已经存在,在这种情况下它会将新用户附加到 XML 文件,否则它会创建 XML 文件。我可以将它作为流结果执行 result.exists() 吗?我不应该只在 Try{ } 中为追加创建 streamresult 对象吗?
      • @user1371330 我错过了那部分。如果您想在文件存在的情况下始终追加用户,则只有一个部分并以追加模式打开文件。如果文件不存在,它将创建它,否则它将追加。
      • 所以我只需要更改 StreamResult result = new StreamResult(new File("C:\\Users\\Steven\\Workspace\\twitter\\src\\users.xml")) ;到第二部分的 FileWriter 并完全删除 if 语句?另外你知道如何让 id 属性比之前输入的用户 id 属性多一个吗?非常感谢!你已经很有帮助了。
      • @user1371330 删除您的 if-else 并将 StreamResult 更改为 StreamResult result = new StreamResult( new FileWriter("C:\\Users\\Steven\\Workspace\\twitter\\src\\users.xml", true));
      • 解决了附加问题!万分感谢。现在我唯一的问题是使 id 属性的值比前一个多一个。有什么想法吗?
      猜你喜欢
      • 2021-07-11
      • 1970-01-01
      • 2018-06-30
      • 2016-10-05
      • 2013-03-24
      • 1970-01-01
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多