我想将XML文件用作数据库。我想要存储ID及其相应的String路径。像:
<item>
<Id>id</Id>
<Path>path</Path>
</item>
或者那样。 现在,在运行时,名称 - 值集合将加载存储在XML文档中的此数据,并根据某些数据检查Id,并相应地进行处理,并更新(即相同Id的更改路径)和删除(删除现有项目)该XML文件中需要items。 希望我能让你理解我的想法! 我没有代码可以显示,因为这是概念级别的。我需要的是我怎样才能实现这一点,是否有任何我可以阅读的教程或API可以做到这一点? 谢谢。我在JAVA。
答案 0 :(得分:5)
另一方面,如果使用提供XML数据库API的XML-Database Systems,则更接近XML。与Exist或Apache Xindice一样。
答案 1 :(得分:4)
我认为这对你的应用来说实际上是一个好主意 - 这是一个完全不同的讨论。
我会将此视为三个独立的问题:
Map<String, String>
)您的大部分代码可能都不会意识到您的集合将以XML格式存储。
Java提供了各种各样的XML API - 内置的API可能会非常难以使用。我不知道最新和最伟大的是什么,但历史上JDOM已经证明相当简单。
请注意,您选择的内存中集合将取决于您的要求 - 例如,排序是否重要?
答案 2 :(得分:3)
这会严重缩放,因为每当更改数据时都必须重写整个XML文件。想象一下,你有100000个条目,并考虑在使用这个数据库时你需要做多少工作。
作为内存中散列映射的序列化形式,它是另一回事,因为HashMap查找速度非常快。但是,序列化hashmap的最简单,最快捷的方法是在标准库中使用内置的XMLSerializer。
答案 3 :(得分:1)
BaseX是一个数据库XML,接缝可以提供您想要做的事情!
答案 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>