要以BDB XML管理XML文档,必须将它们加载到容器中。 通常,我们将通过直接使用XmlContainer句柄来完成此操作。 我们还可以将文档加载到XmlDocument实例中,然后使用XmlContainer句柄将该实例加载到容器中。 本书主要使用第一种,最直接的方法。
将文档添加到容器时,必须标识文档所在的位置。 你可以通过使用:
XmlManager.createLocalFileInputStream()
创建输入流。Xerces
时,输入流才有效。
XmlManager.createURLInputStream()
创建输入流。XmlManager.createMemBufInputStream()
创建输入流。XmlManager.createStdInInputStream()
创建输入流请注意,在我们实际尝试将文档放入容器之前,BDB XML不会验证输入流。
这意味着您可以创建到无效位置或无效内容的输入流,并且在您实际尝试从该位置加载数据之前,BDB XML不会引发异常。我们在下一节中提供了创建输入流的示例。
要将文档添加到容器,请使用XmlContainer.putDocument()
使用此方法时,您必须:
以某种方式获取要放入容器的文档。
为此,我们可以创建内容的输入流或将XML文档加载到字符串对象中。或者,我们可以将文档加载到XmlDocument对象中,然后将XmlDocument对象提供给XmlContainer.putDocument()
。执行此操作时,可以使用输入流或字符串将文档提供给XmlDocument对象,也可以使用事件编写器构造文档。
提供文档的名称。
此名称必须是唯一的,否则BDB XML将抛XmlException.UNIQUE_ERROR
。
如果使用XmlDocument对象添加文档,请使用XmlDocument.setName()
设置文档的名称。否则,您可以直接在调用XmlContainer.putDocument()
时设置名称。
XmlDocumentConfig.setGenerateName()
设置为true,然后将该对象传递给XmlContainer.putDocument()
。这会导致BDB XML为您生成唯一的名称。它生成的名称是唯一值,下划线和我们为文档名称提供的值的串联(如果有)。例如:myDocName_a
dbxml_b
XmlDocumentConfig.setGenerateName(true)
,则BDB XML将抛出XmlException.UNIQUE_ERROR。请注意,
- 我们提供给
XmlContainer.putDocument()
的内容将被读取和验证。- 默认情况下,这包括文档可能引用的任何架构或DTD。 由于这会导致一些性能问题,因此可以使BDBXML仅通过
XmlDocumentConfig.setWellFormedOnly()
设置为true来检查文档正文本身,然后将该对象传递XmlContainer.putDocument()
。
但是,如果文档引用可能来自架构或DTD的信息,则使用此选项会导致解析错误。- 此外,请注意,虽然您的文档与其共享文本实体(如果有)一起存储在容器中,但基础XML解析器会尝试扩展它们以用于索引目的。
因此,您必须确保文档中包含的任何实体在加载时都可以解析。
例如,要添加以字符串形式保存的文档:
package dbxml.gettingStarted;
import com.sleepycat.dbxml.XmlContainer;
import com.sleepycat.dbxml.XmlDocumentConfig;
import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlManager;
import java.io.FileNotFoundException;
public class doDbXml{
public static void main(String args[]) {
XmlManager myManager = null;
XmlContainer myContainer = null;
// The document
String docString = "<a_node><b_node>Some text</b_node></a_node>";
// The document's name.
String docName = "testDoc1";
try {
myManager = new XmlManager();
// Assumes the container currently exists.
myContainer = myManager.openContainer("container.bdbxml");
// Do the actual put
myContainer.putDocument(docName,docString,new XmlDocumentConfig());
} catch (XmlException e) {
// Error handling goes here. You may want to check
// for XmlException.UNIQUE_ERROR, which is raised
// if a document with that name already exists in
// the container. If this exception is thrown,
// try the put again with a different name.
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (myContainer != null) {
myContainer.close();
}
if (myManager != null) {
myManager.close();
}
} catch (XmlException ce) {
// Exception handling goes here
}
}
}
}
要从输入流加载文档,除了在XmlManager上使用适当的方法获取流之外,代码是相同的。 例如,要直接从磁盘上的文件加载XmlDocument:
package dbxml.gettingStarted;
import com.sleepycat.dbxml.*;
import java.io.FileNotFoundException;
public class doDbXml {
public static void main(String args[]) {
XmlManager myManager = null;
XmlContainer myContainer = null;
// The document
String fileName= "/export/testdoc1.xml";
// The document's name.
String docName = "testDoc1";
try {
myManager = new XmlManager();
// Assumes the container currently exists.
myContainer = myManager.openContainer("container.bdbxml");
// Get the input stream.
XmlInputStream theStream = myManager.createLocalFileInputStream(fileName);
// Do the actual put
myContainer.putDocument(docName, // The document's name
theStream, // The actual document.
new XmlDocumentConfig()); // XmlDocumentConfig object
} catch (XmlException e) {
// Error handling goes here. You may want to check
// for XmlException.UNIQUE_ERROR, which is raised
// if a document with that name already exists in
// the container. If this exception is thrown,
// try the put again with a different name.
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (myContainer != null) {
myContainer.close();
}
if (myManager != null) {
myManager.close();
}
} catch (XmlException ce) {
// Exception handling goes here
}
}
}
}
在上一节中,我们展示了如何通过从磁盘读取文档或将文档作为字符串对象提供,将文档加载到容器中。 或者,我们可以使用XmlEventWriter类对象构造文档,该对象将文档存储在XmlDocument对象中。 然后,您可以将该XmlDocument对象放入容器,如上一节中所述。
XmlEventWriter提供的方法允许您描述文档的各个离散部分。 例如,如果您已经使用SAX解析器解析文档并且希望将解析器发现的信息写入容器,那么它很有用。
要使用事件编写器
创建XmlDocument
实例。
使用XmlDocument.setName()
方法为其命名。
使用XmlContainer.putDocumentAsEventWriter()
方法将文档放入容器中。请注意,此时您实际上没有将任何文档数据写入容器,因为您的文档当前是空的。
此方法返回
XmlEventWriter
对象。
使用XmlEventWriter
对象启动新文档。
您可以使用XmlEventWriter.writeStartDocument()
方法执行此操作,该方法允许您描述有关XML文档的信息,例如其编码及其XML版本标识。
启动文档后,您可以编写开始和结束元素,属性,处理指令,文本,CDATA以及您可能希望放在XML文档上的所有其他功能。 XmlEventWriter
提供了允许您执行这些操作的方法。
完成文档后,使用XmlEventWriter.close()
方法关闭它。这样就完成了您在步骤3中开始的容器放置操作。
例如,假设您要将以下文档写入容器:
<a>
<b a1="one" b2="two">b node text</b>
<c>c node text</c>
</a>
然后,以下代码片段将完成该任务:
// Manager and container opens omitted for brevity.
// create a new document
XmlDocument doc = mgr.createDocument();
doc.setName(dname);
XmlEventWriter writer =
container.putDocumentAsEventWriter(doc);
writer.writeStartDocument(null, null, null); // no XML decl
// Write the document's root node. It has no prefixes or
// attributes. This node is not empty.
writer.writeStartElement("a", null, null, 0, false);
// Write a new start element. This time for the "b" node.
// It has two attributes and its content is also not empty.
writer.writeStartElement("b", null, null, 2, false);
// Write the "a1" and "b2" attributes on the "b" node
writer.writeAttribute("a1", null, null, "one", true);
writer.writeAttribute("b2", null, null, "two", true);
// Write the "b" node's content. Note that there are 11
// characters in this text, and we provide that information
// to the method.
writer.writeText(XmlManager.Characters, "b node text", 11);
// End the "b" node
writer.writeEndElement("b", null, null);
// Start the "c" node. There are no attributes on this node.
writer.writeStartElement("c", null, null, 0, false);
// Write the "c" node's content
writer.writeText(XmlManager.Characters, "c node text", 11);
// End the "c" node and then the "a" (the root) node
writer.writeEndElement("c", null, null);
writer.writeEndElement("a", null, null);
// End the document
writer.writeEndDocument();
// Close the document
writer.close();
存储在BDB XML中的每个XML文档实际上都包含两种信息:文档本身和元数据。
Metadata(元数据)可以包含任意复杂的信息集。通常,它包含有关您未在文档中包含或不包含在文档中的文档的信息。例如,您可以携带有关将文档添加到容器,上次修改或可能是到期时间的日期和时间的信息。元数据还可用于存储有关BDB XML外部文档的信息,例如最初存储文档的磁盘上位置,或者可能包含有关文档维护者可能有用的文档的注释。
换句话说,元数据可以包含任何内容–BDB XML对您可以使用它的内容没有任何限制。此外,您可以查询和索引元数据(有关更多信息,请参阅使用BDB XML索引)。甚至可以在容器中包含仅包含元数据的文档。
要将元数据设置到文档中,您必须:
(可选)(但建议)为每条元数据(以字符串形式)创建URI
。
创建一个用于元数据的属性名称,同样以字符串的形式。
创建属性值 - 要在文档上携带的实际元数据信息 - 作为XmlValue
或作为Java byte[]
数组。
在XmlDocument
对象上设置此信息。
(可选)(但通常)将实际的XML文档设置为相同的XmlDocument
对象。
将XmlDocument添加到容器中。
package dbxml.gettingStarted;
import com.sleepycat.dbxml.*;
import java.io.FileNotFoundException;
public class doDbXml {
public static void main(String args[]) {
XmlManager myManager = null;
XmlContainer myContainer = null;
// The document
String fileName = "/export/testdoc1.xml";
// The document's name.
String docName = "testDoc1";
try {
// URI, attribute name, and attribute value used for
// the metadata. We will carry a timestamp here
// (hard coded for clarity purposes).
String URI = "http://dbxmlExamples/metadata";
String attrName = "createdOn";
XmlValue attrValue =
new XmlValue(XmlValue.DATE_TIME, "2005-10-5T04:18:36");
myManager = new XmlManager();
// Assumes the container currently exists.
myContainer =
myManager.openContainer("container.bdbxml");
// Get the input stream.
XmlInputStream theStream = myManager.createLocalFileInputStream(fileName);
// Get an XmlDocument
XmlDocument myDoc = myManager.createDocument();
// Set the document's name
myDoc.setName(docName);
// Set the content
myDoc.setContentAsXmlInputStream(theStream);
// Set the metadata
myDoc.setMetaData(URI, attrName, attrValue);
// Put the document into the container
myContainer.putDocument(myDoc, // The actual document.
new XmlDocumentConfig()); // XmlDocumentConfig object
} catch (XmlException e) {
// Error handling goes here. You may want to check
// for XmlException.UNIQUE_ERROR, which is raised
// if a document with that name already exists in
// the container. If this exception is thrown,
// try the put again with a different name.
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (myContainer != null) {
myContainer.close();
}
if (myManager != null) {
myManager.close();
}
} catch (XmlException ce) {
// Exception handling goes here
}
}
}
}
最近公司要忙其他技术方向了,暂时停止这方面博文更新。
如果有喜欢这方面博文的道友,请留言,只要有一个喜欢我就把它更新完~
之前这几章内容,总结了一个Demo ,有需要的可以拿去。
https://github.com/geekxingyun/Oracle-Berkeley-DB/tree/master/berkeleydbxmlsample