在Java中使用XML作为数据库

时间:2011-01-30 12:12:24

标签: java xml

我想将XML文件用作数据库。我想要存储ID及其相应的String路径。像:

<item>
     <Id>id</Id>
     <Path>path</Path>
</item> 

或者那样。 现在,在运行时,名称 - 值集合将加载存储在XML文档中的此数据,并根据某些数据检查Id,并相应地进行处理,并更新(即相同Id的更改路径)和删除(删除现有项目)该XML文件中需要items。 希望我能让你理解我的想法! 我没有代码可以显示,因为这是概念级别的。我需要的是我怎样才能实现这一点,是否有任何我可以阅读的教程或API可以做到这一点? 谢谢。我在JAVA。

5 个答案:

答案 0 :(得分:5)

另一方面,如果使用提供XML数据库API的XML-Database Systems,则更接近XML。与ExistApache Xindice一样。

答案 1 :(得分:4)

我认为这对你的应用来说实际上是一个好主意 - 这是一个完全不同的讨论。

我会将此视为三个独立的问题:

  • 从磁盘加载XML文件并将其存储在适当的数据结构中(例如Map<String, String>
  • 适当地操作集合(获取,添加或删除条目)
  • 将XML文件保存回磁盘

您的大部分代码可能都不会意识到您的集合将以XML格式存储。

Java提供了各种各样的XML API - 内置的API可能会非常难以使用。我不知道最新和最伟大的是什么,但历史上JDOM已经证明相当简单。

请注意,您选择的内存中集合将取决于您的要求 - 例如,排序是否重要?

答案 2 :(得分:3)

这会严重缩放,因为每当更改数据时都必须重写整个XML文件。想象一下,你有100000个条目,并考虑在使用这个数据库时你需要做多少工作。

作为内存中散列映射的序列化形式,它是另一回事,因为HashMap查找速度非常快。但是,序列化hashmap的最简单,最快捷的方法是在标准库中使用内置的XMLSerializer。

答案 3 :(得分:1)

BaseX是一个数据库XML,接缝可以提供您想要做的事情!

http://basex.org/

答案 4 :(得分:0)

我更喜欢使用Joox,一个流畅的api来管理类似jquery的dom。它没有依赖关系,你可以用maven安装。

仅仅因为java性能,使用属性比使用元素更好*(来自coleages的体验)。

所以我建议你以这种方式使用你的模型:

<items>
     <item id="1" path="path"/>
     ...
</items>

我为你使用Joox创建了这个类:

package test;
import static org.joox.JOOX.$;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.apache.commons.io.FileUtils;
import org.joox.JOOX;
import org.joox.Match;
import org.xml.sax.SAXException;
    public class XmlDBTable{
        private Match dbMatch;
        private String xmlBeforeCommit;
        private boolean building;
        private String root;
        private String item;
        private String itemXpathTemplate;
        private File file;
        public void setRoot(String root){
            this.root=root;
        }
        public void setItemTemplate(String item){
            this.item=item;
        }
        public void setItemXpathTemplate(String itemXpath){
            this.itemXpathTemplate=itemXpath;
        }
        public void setFile(String path){
            file=new File(path);
            if(file.exists())
                try {
                    dbMatch=$(file);
                } catch (SAXException | IOException e) {
                    e.printStackTrace();
                }
        }
        public Match xml() {
            Match dbMatch= dbMatch();
            building=true;
            return dbMatch;
        }
        public void insertOrUpdate(String keyEqualsValueList){
            Match dbMatch= dbMatch();
            String newItem=item;
            if(keyEqualsValueList.contains(",")) {
                String[] keyValues=keyEqualsValueList.split(",");
                for(String keyValue:keyValues) {
                    String key=keyValue.split("=")[0].toUpperCase();
                    String value=keyValue.split("=")[1];
                    newItem=newItem.replace(key,value);
                }
            }else {
                String key=keyEqualsValueList.split("=")[0].toUpperCase();
                String value=keyEqualsValueList.split("=")[1];
                newItem=newItem.replace(key,value);
            }
            String id=itemId(newItem);
            String itemXpath=itemXpath(id);
            Match item=$(dbMatch).xpath(itemXpath);
            if ($(item).isEmpty()){
                $(dbMatch).append(newItem);
            }else{
                if(keyEqualsValueList.contains(",")) {
                    String[] keyValues=keyEqualsValueList.split(",");
                    for(String keyValue:keyValues) {
                        String key=keyValue.split("=")[0];
                        String value=keyValue.split("=")[1];
                        $(dbMatch).xpath(itemXpath).attr(key,value);
                    }
                }else {
                    String key=keyEqualsValueList.split("=")[0].toUpperCase();
                    String value=keyEqualsValueList.split("=")[1];
                    $(dbMatch).xpath(itemXpath).attr(key,value);
                }
            }
            building=true;
            System.out.println("Item id "+id+" added ok");
        }
        public void delete(String id){
            Match dbMatch= dbMatch();
            String itemXpath=itemXpath(id);
            Match item=$(dbMatch).xpath(itemXpath);
            if (!$(item).isEmpty()){
                $(dbMatch).xpath(itemXpath).remove();
                System.out.println("Item id "+id+" deleted ok");
            }else{
                System.out.println("The item didn't exist");
            }
            building=true;
        }
        private String itemId(String item) {
            String id=xmlStrToMatch(item, "UTF-8").attr("id");
            return id;
        }
        private String itemXpath(String id) {
            String itemXpath=itemXpathTemplate.replace("ID", id);
            return itemXpath;
        }
        public synchronized boolean commit(){
            try {
                FileUtils.writeStringToFile(file,dbMatch().toString(),"UTF-8");
                building=false;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return true;
        }
        public boolean rollBack(){
            dbMatch();
            dbMatch=xmlStrToMatch(xmlBeforeCommit, "UTF-8");
            System.out.println("Removed all changes after last commit");
            building=false;
            return true;
        }
        private Match dbMatch(){
            if(dbMatch==null){
                dbMatch=xmlStrToMatch(root,"UTF-8");
            }
            if(!building){
                if(xmlBeforeCommit!=null){
                    xmlBeforeCommit=dbMatch.toString();
                }else {
                    xmlBeforeCommit=root;
                }
            }
            return dbMatch;
        }
        private static Match xmlStrToMatch(String xmlString, String encoding){
            Match match = null;
            try {
                match = $(JOOX.builder().parse(new ByteArrayInputStream(xmlString.getBytes(encoding))));
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SAXException  e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return match;
        }
    }

要使用它,您可以使用:

package test;

public class ItemsTable{
    public static void main(String... args){
        XmlDBTable itemsTable= new XmlDBTable();
        itemsTable.setRoot("<items></items>");
        itemsTable.setItemTemplate("<item id=\"ID\" path=\"PATH\"/>");
        itemsTable.setItemXpathTemplate("/items/item[@id='ID']");
        itemsTable.setFile("C:\\users\\jesus\\Downloads\\temp\\itemsTable.xml");
        itemsTable.insertOrUpdate("id=1,path=myPath");
        itemsTable.insertOrUpdate("id=2,path=myPath2");
        itemsTable.delete("2");
        itemsTable.insertOrUpdate("id=3,path=myPath3");
        //save changes
        itemsTable.commit();
        //you can use all power of Joox Methods too to do the same or more
        //Select path from item with id=1
        String path1=itemsTable.xml().xpath("//item[@id='1']").attr("path");
        //print it
        System.out.println(path1);
        //Add subItem id=0 to item with id=1
        itemsTable.xml().xpath("//item[@id='1']").append("<subitem id=\"0\" color=\"black\">Super Subitem</subitem>");
        //print the text of subitem recently added
        String subitem1=itemsTable.xml().xpath("//subitem[@id='0']").text();
        System.out.println(subitem1);
        //save changes
        itemsTable.commit();
        //Add subItem id=1 to item with id=1
        itemsTable.xml().xpath("//item[@id='1']").append("<subitem id=\"1\" color=\"blue\">Super Subitem</subitem>");
        //rollback changes after last commit (subitem id=1 in item id=1 deleted)
        itemsTable.rollBack();
        itemsTable.insertOrUpdate("id=4,path=myPath4");
        //save changes
        itemsTable.commit();
    }
}

*请注意,字符串模板使用大写作为默认值,例如。 ID = “ID” *另一种方法insertOrUpdate和delete仅适用于属性作为列。 *您可以使用Joox方法插入新行,如图所示。

这是生成的文件:

<items>
    <item id="1" path="myPath">
        <subitem color="black" id="0">Super Subitem</subitem>
    </item>
    <item id="3" path="myPath3"/>
    <item id="4" path="myPath4"/>
</items>

这是控制台中的输出:

Item id 2 added ok
Item id 2 deleted ok
Item id 3 added ok
myPath
Super Subitem
Removed all changes after last commit
Item id 4 added ok

我的maven依赖项:

<dependency>
    <groupId>org.jooq</groupId>
    <artifactId>joox</artifactId>
    <version>1.4.0</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>