2008-01-14 12:16:58 UTC
I emailed this new tutorial / documentation to the admin a few weeks ago but he didn't respond. So I'm posting it here for the rest of you and anyone who needs it.
-=( ---------------------------------------------------------------------- )=-
-=( kXml and kDoc ----------------------------------------------- Tutorial )=-
-=( ---------------------------------------------------------------------- )=-
-=( 0 : Contents --------------------------------------------------------- )=-
0 : Contents
1 : Version History
2 : Begin Here
3 : Getting a Document in
4 : Getting a Document out
5 : Creating a custom Document
6 : Iterating a Document
7 : Searching a Document
8 : License
-=( 1 : Version History--------------------------------------------------- )=-
17-Dec-2007, CK, Version 1.0
- Initial release. It really only covers kDoc because that's what I use. I
haven't "tested" the code but it's ripped slightly modified from one of my
own programs and it should be self explanatory. Written for 2.3.0.
-=( 2 : Begin Here ------------------------------------------------------- )=-
You should add these imports to your source:
import org.kxml2.io.*;
import org.kxml2.kdom.*;
And if you're using NetBeans, go to
File ->
(Project) Properties ->
Libraries & Resources ->
Add Jar/Zip
And point it to the dist\kxml-x.x.x.jar in the distribution. Now you're
ready to go.
-=( 2 : Getting a Document in -------------------------------------------- )=-
The first thing you'll want to do is get the XML you want to process into a
file and turn it into a Document object. That's easy.
FileConnect fc = null;
InputStream in = null;
Document document = null;
InputStreamReader isr = null;
KXmlParser parser = null;
fc = (FileConnect) Connector.open("
file:///root1/test.xml",
Connector.READ);
in = fc.openInputStream();
document = new Document();
isr = new InputStreamReader(in);
try {
parser.setInput(isr);
Document.parse(parser);
} catch (Exception ioe) {
}
If you were wanting to convert a String to an XML Document instead, try this:
String string = new String("<XML />");
ByteArrayInputStream in = null;
Document document = null;
InputStreamReader isr = null;
KXmlParser parser = null;
in = new ByteArrayInputStream(string.getBytes());
document = new Document();
isr = new InputStreamReader(in);
try {
parser.setInput(isr);
Document.parse(parser);
} catch (Exception ioe) {
}
-=( 3 : Getting a Document out ------------------------------------------- )=-
This is how to go the other way. In this case we'll convert a Document to a
String, which can be really useful for printing to find if you've created or
read a Document object properly.
// Assuming the document object exists from the first example
ByteArrayOutputStream out = null;
KXmlSerializer serializer = null;
out = new ByteArrayOutputStream();
serializer = new KXmlSerializer();
try {
serializer.setOutput(out, null);
document.write(serializer)
serializer.flush();
} catch (Exception ioe) {
}
return out.toString() // Contains the XML
-=( 4 : Creating a custom Document --------------------------------------- )=-
At some stage you might want to create an XML Document yourself. Let's assume
we want to create something like:
<?xml version="1.0" encoding="UTF-8"?>
<CRED>
<CRED_HEADER>
<USERNAME>codykonior</USERNAME>
<PASSWORD>1234567890</PASSWORD>
</CRED_HEADER>
<LIST>
<ITEM>
<NAME>CRED</NAME>
<VERSION>1.0.0</VERSION>
</ITEM>
<ITEM>
<NAME>CRED_ACK</NAME>
<VERSION>1.0.0</VERSION>
</ITEM>
</LIST>
One way to go about it would be using tonnes of Strings and joining them all
together. Or you can use kDoc to create a Document in memory to contain all
that information, and then convert it to a String using the above routine.
This is one way to create that Document.
String username = "codykonior";
String password = "1234567890";
Document document = new Document();
Element cred = new Element();
Element cred_header = new Element();
Element username = new Element();
Element password = new Element();
Element list = new Element();
Element item_1 = new Element();
Element item_1_name = new Element();
Element item_1_version = new Element();
Element item_2 = new Element();
Element item_2_name = new Element();
Element item_2_version = new Element();
// This creates all the XML tag names and content data
cred.setName("CRED");
cred_header.setName("CRED_HEADER");
username.setName("USERNAME");
username.addChild(Node.TEXT, username);
password.setName("PASSWORD");
password.addChild(Node.TEXT, password);
list.setName("LIST");
item_1.setName("ITEM");
item_1_name.setName("NAME");
item_1_name.addChild(Node.TEXT, "CRED");
item_1_version.setName("VERSION");
item_1_version.addChild(Node.TEXT, "1.0.0");
item_2.setName("ITEM");
item_2_name.setName("NAME");
item_2_name.addChild(Node.TEXT, "CRED_ACK");
item_2_version.setName("VERSION");
item_2_version.addChild(Node.TEXT, "1.0.0");
// Now to link everything together, in order
// Link the Header
cred_header.addChild(Node.ELEMENT, username);
cred_header.addChild(Node.ELEMENT, password);
// Link the Items
item_1.addChild(Node.ELEMENT, item_1_name);
item_1.addChild(Node.ELEMENT, item_1_version);
item_2.addChild(Node.ELEMENT, item_2_name);
item_2.addChild(Node.ELEMENT, item_2_version);
// Link Items back to Item
item.addChild(Node.ELEMENT, item_1);
item.addChild(Node.ELEMENT, item_2);
// Link Header and Items to Cred
cred.addChild(Node.ELEMENT, cred_header);
cred.addChild(Node.ELEMENT, item);
// Create the root of the Document
document.addChild(0, Node.ELEMENT, cred);
You'll see if you dump the Document as shown in the previous examples, the XML
text comes out as if you'd generated it by hand. (I agree though, this is a
really long-winded way of doing things).
-=( 5 : Iterating a Document --------------------------------------------- )=-
A good way to get used to the Document format is to iterate through it while
dumping out all of the fields. Here's a way to dump all the information.
String printString = "";
public void iterateDocument(Element element, int nestingLevel) {
if (element != null) {
printString += "Nest: " + nestingLevel + ", Element.getname(): " + element.getName() + "\n";
// Actually haven't used attributes but this should work
for (int attribute = 0; attribute < element.getAttributeCount();
attribute++) {
printString += "Attribute " + element.getAttributeName(attribute)
+ " = " + element.getAttributeValue(attribute) + "\n";
}
for (int child = 0; child < element.getChildCount(); child++) {
if (element.getType(child) == Node.ELEMENT) {
iterateDocument((Element) element.getChild(child),
nestingLevel + 1);
} else if (element.getType(child) == Node.TEXT) {
printString += "Child " + child + " is Text, " +
element.getText(child) + "\n";
} else {
printString += "Child " + child + " isn't an Element\n"; }
}
} else {
printString += "Error: Got Null\n";
}
}
I suggest you call it like:
iterateDocument(document.getRootElement());
-=( 6 : Searching a Document --------------------------------------------- )=-
There are two things you'll commonly search for. One is to search for just a
branch of a Document. For example you might want the first ITEM branch from
our example above, and later want the second ITEM branch.
int lastName = 0;
int currentName = 0;
public Element findNextName(Element thisElement, String searchString) {
Element nextElement = null;
if (thisElement != null) {
if (thisElement.getName().equals(searchString)) {
currentName++;
if (currentName > lastName) {
lastName = currentName;
currentName = 0;
return thisElement;
}
}
for (int child = 0; child < thisElement.getChildCount(); child++) {
if (thisElement.getType(child) == Node.ELEMENT) {
nextElement = findNextName((Element)
thisElement.getChild(child), searchString);
if (nextElement != null) {
return nextElement;
}
}
}
}
return null;
}
You would call this like:
Element item = findNextName(document.getRootElement(), "ITEM");
And later you could get the second ITEM element by calling it again.
Element item = findNextName(document.getRootElement(), "ITEM");
The other case is when you might just want the text value inside a tag, like
you might want the text from NAME tag in the ITEM you just got above.
int lastValue = 0;
int currentValue = 0;
public String findNextValue(Element thisElement, String searchString) {
String nextString = null;
if (thisElement != null) {
for (int child = 0; child < thisElement.getChildCount(); child++) {
if (thisElement.getType(child) == Node.ELEMENT) {
nextString = findNextValue((Element)
thisElement.getChild(child), searchString);
if (nextString != null) {
return nextString;
}
} else if (thisElement.getType(child) == Node.TEXT) {
if (thisElement.getName().equals(searchString)) {
currentValue++;
if (currentValue > lastValue) {
lastValue = currentValue;
currentValue = 0;
return thisElement.getText(child);
}
}
}
}
}
return null;
}
I suggest you call it like:
String name = findNextValue(item, searchString);
-=( 7 : License ---------------------------------------------------------- )=-
(c) 2007, Cody Konior. Licensed to be distributed with kDoc/kXML according
to its licenses, as long as this notice isn't removed. I can be contacted
by email at cody konior at users dot sourceforget dot net, with no spaces :)
-=( ---------------------------------------------------------------------- )=-
-=( kXml and kDoc ----------------------------------------------- Tutorial )=-
-=( ---------------------------------------------------------------------- )=-