Java/XML/XML Data
Содержание
- 1 Common XML constants.
- 2 extends DefaultHandler to create a XML binding
- 3 JAXP 1.3 Datatype API
- 4 Parse and format xs:dateTime values
- 5 Replaces all XML character entities with the character they represent.
- 6 Sniffed Xml InputStream to find out the declaration and file encoding
- 7 Sniffed Xml Reader
- 8 Source To InputSource
- 9 Streaming XML
- 10 Utility class for working with xml data
- 11 whether the given 32 bit character is a valid XML 1.1 character.
- 12 Whether the given character is a valid XML space.
- 13 Your won XML binding
Common XML constants.
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* Contains common XML constants.
*
* @author
* @version $Id: XMLConstants.java 475477 2006-11-15 22:44:28Z cam $
*/
public interface XMLConstants {
// Namespace URIs
String XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
String XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
String XLINK_NAMESPACE_URI = "http://www.w3.org/1999/xlink";
String XML_EVENTS_NAMESPACE_URI = "http://www.w3.org/2001/xml-events";
// Namespace prefixes
String XML_PREFIX = "xml";
String XMLNS_PREFIX = "xmlns";
String XLINK_PREFIX = "xlink";
// xml:{base,id,lang,space} and XML Events attributes
String XML_BASE_ATTRIBUTE = "base";
String XML_ID_ATTRIBUTE = "id";
String XML_LANG_ATTRIBUTE = "lang";
String XML_SPACE_ATTRIBUTE = "space";
String XML_BASE_QNAME = XML_PREFIX + ":" + XML_BASE_ATTRIBUTE;
String XML_ID_QNAME = XML_PREFIX + ":" + XML_ID_ATTRIBUTE;
String XML_LANG_QNAME = XML_PREFIX + ":" + XML_LANG_ATTRIBUTE;
String XML_SPACE_QNAME = XML_PREFIX + ":" + XML_SPACE_ATTRIBUTE;
String XML_DEFAULT_VALUE = "default";
String XML_PRESERVE_VALUE = "preserve";
String XML_EVENTS_EVENT_ATTRIBUTE = "event";
// XLink attributes
String XLINK_HREF_ATTRIBUTE = "href";
String XLINK_HREF_QNAME = XLINK_PREFIX + ":" + XLINK_HREF_ATTRIBUTE;
// Serialization constants
String XML_TAB = " ";
String XML_OPEN_TAG_END_CHILDREN = " >";
String XML_OPEN_TAG_END_NO_CHILDREN = " />";
String XML_OPEN_TAG_START = "<";
String XML_CLOSE_TAG_START = "</";
String XML_CLOSE_TAG_END = ">";
String XML_SPACE = " ";
String XML_EQUAL_SIGN = "=";
String XML_EQUAL_QUOT = "=\"";
String XML_DOUBLE_QUOTE = "\"";
char XML_CHAR_QUOT = "\"";
char XML_CHAR_LT = "<";
char XML_CHAR_GT = ">";
char XML_CHAR_APOS = "\"";
char XML_CHAR_AMP = "&";
String XML_ENTITY_QUOT = """;
String XML_ENTITY_LT = "<";
String XML_ENTITY_GT = ">";
String XML_ENTITY_APOS = "'";
String XML_ENTITY_AMP = "&";
String XML_CHAR_REF_PREFIX = "&#x";
String XML_CHAR_REF_SUFFIX = ";";
String XML_CDATA_END = "]]>";
String XML_DOUBLE_DASH = "--";
String XML_PROCESSING_INSTRUCTION_END = "?>";
// XML versions
String XML_VERSION_10 = "1.0";
String XML_VERSION_11 = "1.1";
}
extends DefaultHandler to create a XML binding
import java.io.File;
import java.util.ArrayList;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
public class SAXSample {
public static void main(String[] args) throws Exception {
File file = new File("book.xml");
SAXParserFactory factory = SAXParserFactory.newInstance();
MyHandler handler = new MyHandler();
SAXParser saxParser = factory.newSAXParser();
saxParser.parse(file, handler);
SAXBooks books = handler.getBooks();
for (int i = 0; i < books.getBookSize(); i++) {
SAXBook book = books.getBook(i);
System.out.println(book);
}
}
}
class MyHandler extends DefaultHandler {
private SAXBooks books;
private boolean readingAuthor;
private boolean readingTitle;
private boolean readingPrice;
public SAXBooks getBooks() {
return this.books;
}
public void startElement(String uri, String localName, String qName, Attributes attributes) {
if (qName.equalsIgnoreCase("books")) {
books = new SAXBooks();
} else if (qName.equalsIgnoreCase("book")) {
SAXBook book = new SAXBook();
for (int i = 0; i < attributes.getLength(); i++) {
if (attributes.getQName(i).equalsIgnoreCase("category")) {
book.setCategory(attributes.getValue(i));
}
}
books.addBook(book);
} else if (qName.equalsIgnoreCase("author")) {
this.readingAuthor = true;
} else if (qName.equalsIgnoreCase("title")) {
this.readingTitle = true;
} else if (qName.equalsIgnoreCase("price")) {
this.readingPrice = true;
} else {
System.out.println("Unknown element: " + qName);
}
}
public void startDocument() {
}
public void endDocument() {
}
public void characters(char[] ch, int start, int length) {
String chars = new String(ch, start, length).trim();
if (chars.length() == 0) {
return;
}
SAXBook book = books.getLastBook();
if (readingAuthor) {
book.setAuthor(chars);
} else if (readingTitle) {
book.setTitle(chars);
} else if (readingPrice) {
book.setPrice(Float.parseFloat(chars));
}
}
public void endElement(String uri, String localName, String qName) {
if (qName.equalsIgnoreCase("author")) {
this.readingAuthor = false;
} else if (qName.equalsIgnoreCase("title")) {
this.readingTitle = false;
} else if (qName.equalsIgnoreCase("price")) {
this.readingPrice = false;
}
}
}
class SAXBook {
private String title;
private String author;
private String category;
private float price;
public SAXBook() {
}
public SAXBook(String title, String author, String category, float price) {
this.title = title;
this.author = author;
this.category = category;
this.price = price;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return this.author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getCategory() {
return this.category;
}
public void setCategory(String category) {
this.category = category;
}
public float getPrice() {
return this.price;
}
public void setPrice(float price) {
this.price = price;
}
public String toString() {
return "Book: " + title + ", " + category + ", " + author + ", " + price;
}
}
class SAXBooks {
private ArrayList<SAXBook> bookList = new ArrayList<SAXBook>();
public SAXBooks() {
}
public void addBook(SAXBook book) {
this.bookList.add(book);
}
public SAXBook getBook(int index) {
if (index >= bookList.size()) {
return null;
}
return (SAXBook) bookList.get(index);
}
public SAXBook getLastBook() {
return this.getBook(this.getBookSize() - 1);
}
public int getBookSize() {
return bookList.size();
}
}
<books>
<book category="fiction">
<title>title 1</title>
<author>Tim Lahaye</author>
<price>14.95</price>
</book>
<book category="science fiction">
<title>title 2</title>
<author>Tim Lahaye</author>
<price>14.95</price>
</book>
</books>
JAXP 1.3 Datatype API
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
/**
* <p>
* A sample which demonstrates usage of the JAXP 1.3 Datatype API.
* </p>
*
* @version $Id: DatatypeAPIUsage.java 447685 2006-09-19 02:37:49Z mrglavas $
*/
public class DatatypeAPIUsage {
public static void main(String[] args) {
try {
DatatypeFactory df = DatatypeFactory.newInstance();
// my work number in milliseconds:
Duration myPhone = df.newDuration(9054133519l);
Duration myLife = df.newDuration(true, 29, 2, 15, 13, 45, 0);
int compareVal = myPhone.rupare(myLife);
switch (compareVal) {
case DatatypeConstants.LESSER:
System.out.println("There are fewer milliseconds in my phone number than my lifespan.");
break;
case DatatypeConstants.EQUAL:
System.out
.println("The same number of milliseconds are in my phone number and my lifespan.");
break;
case DatatypeConstants.GREATER:
System.out.println("There are more milliseconds in my phone number than my lifespan.");
break;
case DatatypeConstants.INDETERMINATE:
System.out.println("The comparison could not be carried out.");
}
// create a yearMonthDuration
Duration ymDuration = df.newDurationYearMonth("P12Y10M");
System.out.println("P12Y10M is of type: " + ymDuration.getXMLSchemaType());
// create a dayTimeDuration (really this time)
Duration dtDuration = df.newDurationDayTime("P10DT10H12M0S");
System.out.println("P10DT10H12M0S is of type: " + dtDuration.getXMLSchemaType());
// try to fool the factory!
try {
ymDuration = df.newDurationYearMonth("P12Y10M1D");
} catch (IllegalArgumentException e) {
System.out.println(""duration": P12Y10M1D is not "yearMonthDuration"!!!");
}
XMLGregorianCalendar xgc = df.newXMLGregorianCalendar();
xgc.setYear(1975);
xgc.setMonth(DatatypeConstants.AUGUST);
xgc.setDay(11);
xgc.setHour(6);
xgc.setMinute(44);
xgc.setSecond(0);
xgc.setMillisecond(0);
xgc.setTimezone(5);
xgc.add(myPhone);
System.out
.println("The approximate end of the number of milliseconds in my phone number was "
+ xgc);
// adding a duration to XMLGregorianCalendar
xgc.add(myLife);
System.out.println("Adding the duration myLife to the above calendar:" + xgc);
// create a new XMLGregorianCalendar using the string format of xgc.
XMLGregorianCalendar xgcCopy = df.newXMLGregorianCalendar(xgc.toXMLFormat());
// should be equal-if not what happened!!
if (xgcCopy.rupare(xgc) != DatatypeConstants.EQUAL) {
System.out.println("oooops!");
} else {
System.out.println("Very good: " + xgc + " is equal to " + xgcCopy);
}
} catch (DatatypeConfigurationException dce) {
System.err.println("error: Datatype error occurred - " + dce.getMessage());
dce.printStackTrace(System.err);
}
} // main(String[])
} // DatatypeAPIUsage
Parse and format xs:dateTime values
/*
* Copyright 2003, 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
import java.util.Calendar;
import java.util.TimeZone;
/** <p>An instance of {@link java.text.Format}, which may be used
* to parse and format <code>xs:dateTime</code> values.</p>
*/
public class XsDateTimeFormat extends Format {
private static final long serialVersionUID = 3258131340871479609L;
final boolean parseDate;
final boolean parseTime;
XsDateTimeFormat(boolean pParseDate, boolean pParseTime) {
parseDate = pParseDate;
parseTime = pParseTime;
}
/** Creates a new instance.
*/
public XsDateTimeFormat() {
this(true, true);
}
private int parseInt(String pString, int pOffset, StringBuffer pDigits) {
int length = pString.length();
pDigits.setLength(0);
while (pOffset < length) {
char c = pString.charAt(pOffset);
if (Character.isDigit(c)) {
pDigits.append(c);
++pOffset;
} else {
break;
}
}
return pOffset;
}
public Object parseObject(String pString, ParsePosition pParsePosition) {
if (pString == null) {
throw new NullPointerException("The String argument must not be null.");
}
if (pParsePosition == null) {
throw new NullPointerException("The ParsePosition argument must not be null.");
}
int offset = pParsePosition.getIndex();
int length = pString.length();
boolean isMinus = false;
StringBuffer digits = new StringBuffer();
int year, month, mday;
if (parseDate) {
// Sign
if (offset < length) {
char c = pString.charAt(offset);
if (c == "+") {
++offset;
} else if (c == "-") {
++offset;
isMinus = true;
}
}
offset = parseInt(pString, offset, digits);
if (digits.length() < 4) {
pParsePosition.setErrorIndex(offset);
return null;
}
year = Integer.parseInt(digits.toString());
if (offset < length && pString.charAt(offset) == "-") {
++offset;
} else {
pParsePosition.setErrorIndex(offset);
return null;
}
offset = parseInt(pString, offset, digits);
if (digits.length() != 2) {
pParsePosition.setErrorIndex(offset);
return null;
}
month = Integer.parseInt(digits.toString());
if (offset < length && pString.charAt(offset) == "-") {
++offset;
} else {
pParsePosition.setErrorIndex(offset);
return null;
}
offset = parseInt(pString, offset, digits);
if (digits.length() != 2) {
pParsePosition.setErrorIndex(offset);
return null;
}
mday = Integer.parseInt(digits.toString());
if (parseTime) {
if (offset < length && pString.charAt(offset) == "T") {
++offset;
} else {
pParsePosition.setErrorIndex(offset);
return null;
}
}
} else {
year = month = mday = 0;
}
int hour, minute, second, millis;
if (parseTime) {
offset = parseInt(pString, offset, digits);
if (digits.length() != 2) {
pParsePosition.setErrorIndex(offset);
return null;
}
hour = Integer.parseInt(digits.toString());
if (offset < length && pString.charAt(offset) == ":") {
++offset;
} else {
pParsePosition.setErrorIndex(offset);
return null;
}
offset = parseInt(pString, offset, digits);
if (digits.length() != 2) {
pParsePosition.setErrorIndex(offset);
return null;
}
minute = Integer.parseInt(digits.toString());
if (offset < length && pString.charAt(offset) == ":") {
++offset;
} else {
pParsePosition.setErrorIndex(offset);
return null;
}
offset = parseInt(pString, offset, digits);
if (digits.length() != 2) {
pParsePosition.setErrorIndex(offset);
return null;
}
second = Integer.parseInt(digits.toString());
if (offset < length && pString.charAt(offset) == ".") {
++offset;
offset = parseInt(pString, offset, digits);
if (digits.length() > 0) {
millis = Integer.parseInt(digits.toString());
if (millis > 999) {
pParsePosition.setErrorIndex(offset);
return null;
}
for (int i = digits.length(); i < 3; i++) {
millis *= 10;
}
} else {
millis = 0;
}
} else {
millis = 0;
}
} else {
hour = minute = second = millis = 0;
}
digits.setLength(0);
digits.append("GMT");
if (offset < length) {
char c = pString.charAt(offset);
if (c == "Z") {
// Ignore UTC, it is the default
++offset;
} else if (c == "+" || c == "-") {
digits.append(c);
++offset;
for (int i = 0; i < 5; i++) {
if (offset >= length) {
pParsePosition.setErrorIndex(offset);
return null;
}
c = pString.charAt(offset);
if ((i != 2 && Character.isDigit(c)) ||
(i == 2 && c == ":")) {
digits.append(c);
} else {
pParsePosition.setErrorIndex(offset);
return null;
}
++offset;
}
}
}
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(digits.toString()));
cal.set(isMinus ? -year : year, parseDate ? month-1 : month, mday, hour, minute, second);
cal.set(Calendar.MILLISECOND, millis);
pParsePosition.setIndex(offset);
return cal;
}
private void append(StringBuffer pBuffer, int pNum, int pMinLen) {
String s = Integer.toString(pNum);
for (int i = s.length(); i < pMinLen; i++) {
pBuffer.append("0");
}
pBuffer.append(s);
}
public StringBuffer format(Object pCalendar, StringBuffer pBuffer, FieldPosition pPos) {
if (pCalendar == null) {
throw new NullPointerException("The Calendar argument must not be null.");
}
if (pBuffer == null) {
throw new NullPointerException("The StringBuffer argument must not be null.");
}
if (pPos == null) {
throw new NullPointerException("The FieldPosition argument must not be null.");
}
Calendar cal = (Calendar) pCalendar;
if (parseDate) {
int year = cal.get(Calendar.YEAR);
if (year < 0) {
pBuffer.append("-");
year = -year;
}
append(pBuffer, year, 4);
pBuffer.append("-");
append(pBuffer, cal.get(Calendar.MONTH)+1, 2);
pBuffer.append("-");
append(pBuffer, cal.get(Calendar.DAY_OF_MONTH), 2);
if (parseTime) {
pBuffer.append("T");
}
}
if (parseTime) {
append(pBuffer, cal.get(Calendar.HOUR_OF_DAY), 2);
pBuffer.append(":");
append(pBuffer, cal.get(Calendar.MINUTE), 2);
pBuffer.append(":");
append(pBuffer, cal.get(Calendar.SECOND), 2);
int millis = cal.get(Calendar.MILLISECOND);
if (millis > 0) {
pBuffer.append(".");
append(pBuffer, millis, 3);
}
}
TimeZone tz = cal.getTimeZone();
// JDK 1.4: int offset = tz.getOffset(cal.getTimeInMillis());
int offset = cal.get(Calendar.ZONE_OFFSET);
if (tz.inDaylightTime(cal.getTime())) {
offset += cal.get(Calendar.DST_OFFSET);
}
if (offset == 0) {
pBuffer.append("Z");
} else {
if (offset < 0) {
pBuffer.append("-");
offset = -offset;
} else {
pBuffer.append("+");
}
int minutes = offset / (60*1000);
int hours = minutes / 60;
minutes -= hours * 60;
append(pBuffer, hours, 2);
pBuffer.append(":");
append(pBuffer, minutes, 2);
}
return pBuffer;
}
}
/////////////////////////////////////////////////
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ws.rumons.util.test;
import java.text.Format;
import java.text.ParseException;
import java.util.Calendar;
import java.util.TimeZone;
import org.apache.ws.rumons.util.XsDateFormat;
import org.apache.ws.rumons.util.XsDateTimeFormat;
import org.apache.ws.rumons.util.XsTimeFormat;
import junit.framework.TestCase;
/** <p>Test case for the various instances of {@link java.text.Format},
* which are being used to parse special types like <code>xs:dateTime</code>.</p>
*
* @author
*/
public class XsDateTimeFormatTest extends TestCase {
/** Creates a new test with the given name.
*/
public XsDateTimeFormatTest(String pName) {
super(pName);
}
private Calendar getCalendar(TimeZone pTimeZone) {
Calendar cal = Calendar.getInstance(pTimeZone);
cal.set(2004, 01-1, 14, 03, 12, 07);
cal.set(Calendar.MILLISECOND, 0);
return cal;
}
/** Test for
* {@link org.apache.ws.jaxme.xs.util.XsDateTimeFormat#format(Object, StringBuffer, java.text.FieldPosition)}.
*/
public void testFormatDateTime() {
Calendar cal = getCalendar(TimeZone.getTimeZone("GMT"));
assertEquals(0, cal.get(Calendar.MILLISECOND));
XsDateTimeFormat format = new XsDateTimeFormat();
String got = format.format(cal);
String expect = "2004-01-14T03:12:07Z";
assertEquals(expect, got);
cal = getCalendar(TimeZone.getTimeZone("GMT-03:00"));
assertEquals(0, cal.get(Calendar.MILLISECOND));
got = format.format(cal);
expect = "2004-01-14T03:12:07-03:00";
assertEquals(expect, got);
}
/** Test for
* {@link org.apache.ws.jaxme.xs.util.XsDateTimeFormat#parseObject(String, java.text.ParsePosition)}.
*/
public void testParseDateTime() throws ParseException {
String[] dateTimes = new String[]{
"2004-01-14T03:12:07.000Z",
"2004-01-14T03:12:07",
"2004-01-14T03:12:07-00:00",
"2004-01-14T03:12:07+00:00",
};
XsDateTimeFormat format = new XsDateTimeFormat();
Calendar expect = getCalendar(TimeZone.getTimeZone("GMT"));
for (int i = 0; i < dateTimes.length; i++) {
Calendar got = (Calendar) format.parseObject(dateTimes[0]);
assertEquals(expect, got);
}
String dateTime = "2004-01-14T03:12:07.000-03:00";
expect = getCalendar(TimeZone.getTimeZone("GMT-03:00"));
Calendar got = (Calendar) format.parseObject(dateTime);
assertEquals(expect, got);
}
/** Test for
* {@link org.apache.ws.jaxme.xs.util.XsDateFormat#format(Object, StringBuffer, java.text.FieldPosition)}.
*/
public void testFormatDate() {
Calendar cal = getCalendar(TimeZone.getTimeZone("GMT"));
assertEquals(0, cal.get(Calendar.MILLISECOND));
XsDateFormat format = new XsDateFormat();
String got = format.format(cal);
String expect = "2004-01-14Z";
assertEquals(expect, got);
cal = getCalendar(TimeZone.getTimeZone("GMT-03:00"));
assertEquals(0, cal.get(Calendar.MILLISECOND));
got = format.format(cal);
expect = "2004-01-14-03:00";
assertEquals(expect, got);
}
protected void assertEqualDate(Calendar pExpect, Calendar pGot) {
assertEquals(pExpect.get(Calendar.YEAR), pGot.get(Calendar.YEAR));
assertEquals(pExpect.get(Calendar.MONTH), pGot.get(Calendar.MONTH));
assertEquals(pExpect.get(Calendar.DAY_OF_MONTH), pGot.get(Calendar.DAY_OF_MONTH));
assertEquals(pExpect.getTimeZone(), pGot.getTimeZone());
}
protected void assertEqualTime(Calendar pExpect, Calendar pGot) {
assertEquals(pExpect.get(Calendar.HOUR_OF_DAY), pGot.get(Calendar.HOUR_OF_DAY));
assertEquals(pExpect.get(Calendar.MINUTE), pGot.get(Calendar.MINUTE));
assertEquals(pExpect.get(Calendar.SECOND), pGot.get(Calendar.SECOND));
assertEquals(pExpect.get(Calendar.MILLISECOND), pGot.get(Calendar.MILLISECOND));
assertEquals(pExpect.getTimeZone(), pGot.getTimeZone());
}
/** Test for
* {@link org.apache.ws.jaxme.xs.util.XsDateFormat#parseObject(String, java.text.ParsePosition)}.
*/
public void testParseDate() throws ParseException {
String[] dateTimes = new String[]{
"2004-01-14Z",
"2004-01-14",
"2004-01-14+00:00",
"2004-01-14-00:00",
};
XsDateFormat format = new XsDateFormat();
Calendar expect = getCalendar(TimeZone.getTimeZone("GMT"));
for (int i = 0; i < dateTimes.length; i++) {
Calendar got = (Calendar) format.parseObject(dateTimes[0]);
assertEqualDate(expect, got);
}
String dateTime = "2004-01-14-03:00";
expect = getCalendar(TimeZone.getTimeZone("GMT-03:00"));
Calendar got = (Calendar) format.parseObject(dateTime);
assertEqualDate(expect, got);
}
/** Test for
* {@link org.apache.ws.jaxme.xs.util.XsTimeFormat#format(Object, StringBuffer, java.text.FieldPosition)}.
*/
public void testFormatTime() {
Calendar cal = getCalendar(TimeZone.getTimeZone("GMT"));
assertEquals(0, cal.get(Calendar.MILLISECOND));
XsTimeFormat format = new XsTimeFormat();
String got = format.format(cal);
String expect = "03:12:07Z";
assertEquals(expect, got);
cal = getCalendar(TimeZone.getTimeZone("GMT-03:00"));
assertEquals(0, cal.get(Calendar.MILLISECOND));
got = format.format(cal);
expect = "03:12:07-03:00";
assertEquals(expect, got);
}
/** Test for
* {@link org.apache.ws.jaxme.xs.util.XsTimeFormat#parseObject(String, java.text.ParsePosition)}.
*/
public void testParseTime() throws ParseException {
String[] dateTimes = new String[]{
"03:12:07.000Z",
"03:12:07",
"03:12:07-00:00",
"03:12:07+00:00",
};
XsTimeFormat format = new XsTimeFormat();
Calendar expect = getCalendar(TimeZone.getTimeZone("GMT"));
for (int i = 0; i < dateTimes.length; i++) {
Calendar got = (Calendar) format.parseObject(dateTimes[0]);
assertEqualTime(expect, got);
}
String dateTime = "03:12:07.000-03:00";
expect = getCalendar(TimeZone.getTimeZone("GMT-03:00"));
Calendar got = (Calendar) format.parseObject(dateTime);
assertEqualTime(expect, got);
}
/** Tests, whether e zero as suffix matters in milliseconds.
*/
public void testZeroSuffix() throws Exception {
Format format = new XsDateTimeFormat();
Calendar c1 = (Calendar) format.parseObject("2006-05-03T15:29:17.15Z");
Calendar c2 = (Calendar) format.parseObject("2006-05-03T15:29:17.150Z");
assertEquals(c1, c2);
format = new XsTimeFormat();
c1 = (Calendar) format.parseObject("15:29:17.15Z");
c2 = (Calendar) format.parseObject("15:29:17.150Z");
assertEquals(c1, c2);
}
}
Replaces all XML character entities with the character they represent.
/*
* Copyright Aduna (http://www.aduna-software.ru/) (c) 1997-2006.
*
* Licensed under the Aduna BSD-style license.
*/
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Utils {
/**
* Replaces all XML character entities with the character they represent.
*/
public static String resolveEntities(String text) {
int ampIndex = text.indexOf("&");
if (ampIndex == -1) {
// Text doesn"t contain any entities
return text;
}
StringBuilder sb = new StringBuilder((int)(1.1 * text.length()));
int prevIndex = 0;
while (ampIndex >= 0) {
int colonIndex = text.indexOf(";", ampIndex);
sb.append(text.substring(prevIndex, ampIndex));
sb.append(
resolveEntity( text.substring(ampIndex + 1, colonIndex) )
);
prevIndex = colonIndex + 1;
ampIndex = text.indexOf("&", prevIndex);
}
sb.append(text.substring(prevIndex));
return sb.toString();
}
/**
* Resolves an entity reference or character reference to its value.
*
* @param entName The "name" of the reference. This is the string between
* & and ;, e.g. amp, quot, #65 or #x41.
* @return The value of the supplied reference, or the reference itself
* if it could not be resolved.
*/
public static String resolveEntity(String entName) {
if (entName.startsWith("#")) {
// character reference
StringBuilder sb = new StringBuilder();
if (entName.charAt(1) == "x") {
// Hex-notation
sb.append((char)Integer.parseInt(entName.substring(2), 16));
}
else {
// Dec-notation
sb.append((char)Integer.parseInt(entName.substring(1)));
}
return sb.toString();
}
else if (entName.equals("apos")) {
return """;
}
else if (entName.equals("quot")) {
return "\"";
}
else if (entName.equals("gt")) {
return ">";
}
else if (entName.equals("lt")) {
return "<";
}
else if (entName.equals("amp")) {
return "&";
}
else {
return entName;
}
}
}
Sniffed Xml InputStream to find out the declaration and file encoding
/* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// revised from xmlbeans
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
public class SniffedXmlInputStream extends BufferedInputStream
{
// We don"t sniff more than 192 bytes.
public static int MAX_SNIFFED_BYTES = 192;
public SniffedXmlInputStream(InputStream stream) throws IOException
{
super(stream);
// read byte order marks and detect EBCDIC etc
_encoding = sniffFourBytes();
if (_encoding != null && _encoding.equals("IBM037"))
{
// First four bytes suggest EBCDIC with <?xm at start
String encoding = sniffForXmlDecl(_encoding);
if (encoding != null)
_encoding = encoding;
}
if (_encoding == null)
{
// Haven"t yet determined encoding: sniff for <?xml encoding="..."?>
// assuming we can read it as UTF-8.
_encoding = sniffForXmlDecl("UTF-8");
}
if (_encoding == null)
{
// The XML spec says these two things:
// (1) "In the absence of external character encoding information
// (such as MIME headers), parsed entities which are stored in an
// encoding other than UTF-8 or UTF-16 must begin with a text
// declaration (see 4.3.1 The Text Declaration) containing an
// encoding declaration:"
// (2) "In the absence of information provided by an external
// transport protocol (e.g. HTTP or MIME), it is an error
// for an entity including an encoding declaration to be
// presented to the XML processor in an encoding other than
// that named in the declaration, or for an entity which begins
// with neither a Byte Order Mark nor an encoding declaration
// to use an encoding other than UTF-8."
// Since we"re using a sniffed stream, we do not have external
// character encoding information.
// Since we"re here, we also don"t have a recognized byte order
// mark or an explicit encoding declaration that can be read in
// either ASCII or EBDIC style.
// Therefore, we must use UTF-8.
_encoding = "UTF-8";
}
}
private int readAsMuchAsPossible(byte[] buf, int startAt, int len) throws IOException
{
int total = 0;
while (total < len)
{
int count = read(buf, startAt + total, len - total);
if (count < 0)
break;
total += count;
}
return total;
}
private String sniffFourBytes() throws IOException
{
mark(4);
int skip = 0;
try
{
byte[] buf = new byte[4];
if (readAsMuchAsPossible(buf, 0, 4) < 4)
return null;
long result = 0xFF000000 & (buf[0] << 24) | 0x00FF0000 & (buf[1] << 16) | 0x0000FF00 & (buf[2] << 8) | 0x000000FF & buf[3];
if (result == 0x0000FEFF)
return "UCS-4";
else if (result == 0xFFFE0000)
return "UCS-4";
else if (result == 0x0000003C)
return "UCS-4BE";
else if (result == 0x3C000000)
return "UCS-4LE";
else if (result == 0x003C003F)
return "UTF-16BE";
else if (result == 0x3C003F00)
return "UTF-16LE";
else if (result == 0x3C3F786D)
return null; // looks like US-ASCII with <?xml: sniff
else if (result == 0x4C6FA794)
return "IBM037"; // Sniff for ebdic codepage
else if ((result & 0xFFFF0000) == 0xFEFF0000)
return "UTF-16";
else if ((result & 0xFFFF0000) == 0xFFFE0000)
return "UTF-16";
else if ((result & 0xFFFFFF00) == 0xEFBBBF00)
return "UTF-8";
else return null;
}
finally
{
reset();
}
}
// BUGBUG in JDK: Charset.forName is not threadsafe, so we"ll prime it
// with the common charsets.
private static Charset dummy1 = Charset.forName("UTF-8");
private static Charset dummy2 = Charset.forName("UTF-16");
private static Charset dummy3 = Charset.forName("UTF-16BE");
private static Charset dummy4 = Charset.forName("UTF-16LE");
private static Charset dummy5 = Charset.forName("ISO-8859-1");
private static Charset dummy6 = Charset.forName("US-ASCII");
private static Charset dummy7 = Charset.forName("Cp1252");
private String sniffForXmlDecl(String encoding) throws IOException
{
mark(MAX_SNIFFED_BYTES);
try
{
byte[] bytebuf = new byte[MAX_SNIFFED_BYTES];
int bytelimit = readAsMuchAsPossible(bytebuf, 0, MAX_SNIFFED_BYTES);
// BUGBUG in JDK: Charset.forName is not threadsafe.
Charset charset = Charset.forName(encoding);
Reader reader = new InputStreamReader(new ByteArrayInputStream(bytebuf, 0, bytelimit), charset);
char[] buf = new char[bytelimit];
int limit = 0;
while (limit < bytelimit)
{
int count = reader.read(buf, limit, bytelimit - limit);
if (count < 0)
break;
limit += count;
}
return extractXmlDeclEncoding(buf, 0, limit);
}
finally
{
reset();
}
}
private String _encoding;
public String getXmlEncoding()
{
return _encoding;
}
/* package */ static String extractXmlDeclEncoding(char[] buf, int offset, int size)
{
int limit = offset + size;
int xmlpi = firstIndexOf("<?xml", buf, offset, limit);
if (xmlpi >= 0)
{
int i = xmlpi + 5;
ScannedAttribute attr = new ScannedAttribute();
while (i < limit)
{
i = scanAttribute(buf, i, limit, attr);
if (i < 0)
return null;
if (attr.name.equals("encoding"))
return attr.value;
}
}
return null;
}
private static int firstIndexOf(String s, char[] buf, int startAt, int limit)
{
assert(s.length() > 0);
char[] lookFor = s.toCharArray();
char firstchar = lookFor[0];
searching: for (limit -= lookFor.length; startAt < limit; startAt++)
{
if (buf[startAt] == firstchar)
{
for (int i = 1; i < lookFor.length; i++)
{
if (buf[startAt + i] != lookFor[i])
{
continue searching;
}
}
return startAt;
}
}
return -1;
}
private static int nextNonmatchingByte(char[] lookFor, char[] buf, int startAt, int limit)
{
searching: for (; startAt < limit; startAt++)
{
int thischar = buf[startAt];
for (int i = 0; i < lookFor.length; i++)
if (thischar == lookFor[i])
continue searching;
return startAt;
}
return -1;
}
private static int nextMatchingByte(char[] lookFor, char[] buf, int startAt, int limit)
{
searching: for (; startAt < limit; startAt++)
{
int thischar = buf[startAt];
for (int i = 0; i < lookFor.length; i++)
if (thischar == lookFor[i])
return startAt;
}
return -1;
}
private static int nextMatchingByte(char lookFor, char[] buf, int startAt, int limit)
{
searching: for (; startAt < limit; startAt++)
{
if (buf[startAt] == lookFor)
return startAt;
}
return -1;
}
private static char[] WHITESPACE = new char[] { " ", "\r", "\t", "\n" };
private static char[] NOTNAME = new char[] { "=", " ", "\r", "\t", "\n", "?", ">", "<", "\"", "\"" };
private static class ScannedAttribute
{
public String name;
public String value;
}
private static int scanAttribute(char[] buf, int startAt, int limit, ScannedAttribute attr)
{
int nameStart = nextNonmatchingByte(WHITESPACE, buf, startAt, limit);
if (nameStart < 0)
return -1;
int nameEnd = nextMatchingByte(NOTNAME, buf, nameStart, limit);
if (nameEnd < 0)
return -1;
int equals = nextNonmatchingByte(WHITESPACE, buf, nameEnd, limit);
if (equals < 0)
return -1;
if (buf[equals] != "=")
return -1;
int valQuote = nextNonmatchingByte(WHITESPACE, buf, equals + 1, limit);
if (buf[valQuote] != "\"" && buf[valQuote] != "\"")
return -1;
int valEndquote = nextMatchingByte(buf[valQuote], buf, valQuote + 1, limit);
if (valEndquote < 0)
return -1;
attr.name = new String(buf, nameStart, nameEnd - nameStart);
attr.value = new String(buf, valQuote + 1, valEndquote - valQuote - 1);
return valEndquote + 1;
}
}
Sniffed Xml Reader
/* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// revised from xml beans
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
public class SniffedXmlReader extends BufferedReader {
// We don"t sniff more than 192 bytes.
public static int MAX_SNIFFED_CHARS = 192;
public SniffedXmlReader(Reader reader) throws IOException {
super(reader);
_encoding = sniffForXmlDecl();
}
private int readAsMuchAsPossible(char[] buf, int startAt, int len) throws IOException {
int total = 0;
while (total < len) {
int count = read(buf, startAt + total, len - total);
if (count < 0)
break;
total += count;
}
return total;
}
// BUGBUG in JDK: Charset.forName is not threadsafe, so we"ll prime it
// with the common charsets.
private static Charset dummy1 = Charset.forName("UTF-8");
private static Charset dummy2 = Charset.forName("UTF-16");
private static Charset dummy3 = Charset.forName("UTF-16BE");
private static Charset dummy4 = Charset.forName("UTF-16LE");
private static Charset dummy5 = Charset.forName("ISO-8859-1");
private static Charset dummy6 = Charset.forName("US-ASCII");
private static Charset dummy7 = Charset.forName("Cp1252");
private String sniffForXmlDecl() throws IOException {
mark(MAX_SNIFFED_CHARS);
try {
char[] buf = new char[MAX_SNIFFED_CHARS];
int limit = readAsMuchAsPossible(buf, 0, MAX_SNIFFED_CHARS);
return SniffedXmlInputStream.extractXmlDeclEncoding(buf, 0, limit);
} finally {
reset();
}
}
private String _encoding;
public String getXmlEncoding() {
return _encoding;
}
}
class SniffedXmlInputStream extends BufferedInputStream
{
// We don"t sniff more than 192 bytes.
public static int MAX_SNIFFED_BYTES = 192;
public SniffedXmlInputStream(InputStream stream) throws IOException
{
super(stream);
// read byte order marks and detect EBCDIC etc
_encoding = sniffFourBytes();
if (_encoding != null && _encoding.equals("IBM037"))
{
// First four bytes suggest EBCDIC with <?xm at start
String encoding = sniffForXmlDecl(_encoding);
if (encoding != null)
_encoding = encoding;
}
if (_encoding == null)
{
// Haven"t yet determined encoding: sniff for <?xml encoding="..."?>
// assuming we can read it as UTF-8.
_encoding = sniffForXmlDecl("UTF-8");
}
if (_encoding == null)
{
// The XML spec says these two things:
// (1) "In the absence of external character encoding information
// (such as MIME headers), parsed entities which are stored in an
// encoding other than UTF-8 or UTF-16 must begin with a text
// declaration (see 4.3.1 The Text Declaration) containing an
// encoding declaration:"
// (2) "In the absence of information provided by an external
// transport protocol (e.g. HTTP or MIME), it is an error
// for an entity including an encoding declaration to be
// presented to the XML processor in an encoding other than
// that named in the declaration, or for an entity which begins
// with neither a Byte Order Mark nor an encoding declaration
// to use an encoding other than UTF-8."
// Since we"re using a sniffed stream, we do not have external
// character encoding information.
// Since we"re here, we also don"t have a recognized byte order
// mark or an explicit encoding declaration that can be read in
// either ASCII or EBDIC style.
// Therefore, we must use UTF-8.
_encoding = "UTF-8";
}
}
private int readAsMuchAsPossible(byte[] buf, int startAt, int len) throws IOException
{
int total = 0;
while (total < len)
{
int count = read(buf, startAt + total, len - total);
if (count < 0)
break;
total += count;
}
return total;
}
private String sniffFourBytes() throws IOException
{
mark(4);
int skip = 0;
try
{
byte[] buf = new byte[4];
if (readAsMuchAsPossible(buf, 0, 4) < 4)
return null;
long result = 0xFF000000 & (buf[0] << 24) | 0x00FF0000 & (buf[1] << 16) | 0x0000FF00 & (buf[2] << 8) | 0x000000FF & buf[3];
if (result == 0x0000FEFF)
return "UCS-4";
else if (result == 0xFFFE0000)
return "UCS-4";
else if (result == 0x0000003C)
return "UCS-4BE";
else if (result == 0x3C000000)
return "UCS-4LE";
else if (result == 0x003C003F)
return "UTF-16BE";
else if (result == 0x3C003F00)
return "UTF-16LE";
else if (result == 0x3C3F786D)
return null; // looks like US-ASCII with <?xml: sniff
else if (result == 0x4C6FA794)
return "IBM037"; // Sniff for ebdic codepage
else if ((result & 0xFFFF0000) == 0xFEFF0000)
return "UTF-16";
else if ((result & 0xFFFF0000) == 0xFFFE0000)
return "UTF-16";
else if ((result & 0xFFFFFF00) == 0xEFBBBF00)
return "UTF-8";
else return null;
}
finally
{
reset();
}
}
// BUGBUG in JDK: Charset.forName is not threadsafe, so we"ll prime it
// with the common charsets.
private static Charset dummy1 = Charset.forName("UTF-8");
private static Charset dummy2 = Charset.forName("UTF-16");
private static Charset dummy3 = Charset.forName("UTF-16BE");
private static Charset dummy4 = Charset.forName("UTF-16LE");
private static Charset dummy5 = Charset.forName("ISO-8859-1");
private static Charset dummy6 = Charset.forName("US-ASCII");
private static Charset dummy7 = Charset.forName("Cp1252");
private String sniffForXmlDecl(String encoding) throws IOException
{
mark(MAX_SNIFFED_BYTES);
try
{
byte[] bytebuf = new byte[MAX_SNIFFED_BYTES];
int bytelimit = readAsMuchAsPossible(bytebuf, 0, MAX_SNIFFED_BYTES);
// BUGBUG in JDK: Charset.forName is not threadsafe.
Charset charset = Charset.forName(encoding);
Reader reader = new InputStreamReader(new ByteArrayInputStream(bytebuf, 0, bytelimit), charset);
char[] buf = new char[bytelimit];
int limit = 0;
while (limit < bytelimit)
{
int count = reader.read(buf, limit, bytelimit - limit);
if (count < 0)
break;
limit += count;
}
return extractXmlDeclEncoding(buf, 0, limit);
}
finally
{
reset();
}
}
private String _encoding;
public String getXmlEncoding()
{
return _encoding;
}
/* package */ static String extractXmlDeclEncoding(char[] buf, int offset, int size)
{
int limit = offset + size;
int xmlpi = firstIndexOf("<?xml", buf, offset, limit);
if (xmlpi >= 0)
{
int i = xmlpi + 5;
ScannedAttribute attr = new ScannedAttribute();
while (i < limit)
{
i = scanAttribute(buf, i, limit, attr);
if (i < 0)
return null;
if (attr.name.equals("encoding"))
return attr.value;
}
}
return null;
}
private static int firstIndexOf(String s, char[] buf, int startAt, int limit)
{
assert(s.length() > 0);
char[] lookFor = s.toCharArray();
char firstchar = lookFor[0];
searching: for (limit -= lookFor.length; startAt < limit; startAt++)
{
if (buf[startAt] == firstchar)
{
for (int i = 1; i < lookFor.length; i++)
{
if (buf[startAt + i] != lookFor[i])
{
continue searching;
}
}
return startAt;
}
}
return -1;
}
private static int nextNonmatchingByte(char[] lookFor, char[] buf, int startAt, int limit)
{
searching: for (; startAt < limit; startAt++)
{
int thischar = buf[startAt];
for (int i = 0; i < lookFor.length; i++)
if (thischar == lookFor[i])
continue searching;
return startAt;
}
return -1;
}
private static int nextMatchingByte(char[] lookFor, char[] buf, int startAt, int limit)
{
searching: for (; startAt < limit; startAt++)
{
int thischar = buf[startAt];
for (int i = 0; i < lookFor.length; i++)
if (thischar == lookFor[i])
return startAt;
}
return -1;
}
private static int nextMatchingByte(char lookFor, char[] buf, int startAt, int limit)
{
searching: for (; startAt < limit; startAt++)
{
if (buf[startAt] == lookFor)
return startAt;
}
return -1;
}
private static char[] WHITESPACE = new char[] { " ", "\r", "\t", "\n" };
private static char[] NOTNAME = new char[] { "=", " ", "\r", "\t", "\n", "?", ">", "<", "\"", "\"" };
private static class ScannedAttribute
{
public String name;
public String value;
}
private static int scanAttribute(char[] buf, int startAt, int limit, ScannedAttribute attr)
{
int nameStart = nextNonmatchingByte(WHITESPACE, buf, startAt, limit);
if (nameStart < 0)
return -1;
int nameEnd = nextMatchingByte(NOTNAME, buf, nameStart, limit);
if (nameEnd < 0)
return -1;
int equals = nextNonmatchingByte(WHITESPACE, buf, nameEnd, limit);
if (equals < 0)
return -1;
if (buf[equals] != "=")
return -1;
int valQuote = nextNonmatchingByte(WHITESPACE, buf, equals + 1, limit);
if (buf[valQuote] != "\"" && buf[valQuote] != "\"")
return -1;
int valEndquote = nextMatchingByte(buf[valQuote], buf, valQuote + 1, limit);
if (valEndquote < 0)
return -1;
attr.name = new String(buf, nameStart, nameEnd - nameStart);
attr.value = new String(buf, valQuote + 1, valEndquote - valQuote - 1);
return valEndquote + 1;
}
}
Source To InputSource
/*
* Copyright 2003-2008 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
public class Main {
public static void ElementToStream(Element element, OutputStream out) {
try {
DOMSource source = new DOMSource(element);
StreamResult result = new StreamResult(out);
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.transform(source, result);
} catch (Exception ex) {
}
}
/**
* Utility to get the bytes uri
*
* @param source the resource to get
*/
public static InputSource sourceToInputSource(Source source) {
if (source instanceof SAXSource) {
return ((SAXSource) source).getInputSource();
} else if (source instanceof DOMSource) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Node node = ((DOMSource) source).getNode();
if (node instanceof Document) {
node = ((Document) node).getDocumentElement();
}
Element domElement = (Element) node;
ElementToStream(domElement, baos);
InputSource isource = new InputSource(source.getSystemId());
isource.setByteStream(new ByteArrayInputStream(baos.toByteArray()));
return isource;
} else if (source instanceof StreamSource) {
StreamSource ss = (StreamSource) source;
InputSource isource = new InputSource(ss.getSystemId());
isource.setByteStream(ss.getInputStream());
isource.setCharacterStream(ss.getReader());
isource.setPublicId(ss.getPublicId());
return isource;
} else {
return getInputSourceFromURI(source.getSystemId());
}
}
/**
* Utility to get the bytes uri.
* Does NOT handle authenticated URLs,
* use getInputSourceFromURI(uri, username, password)
*
* @param uri the resource to get
*/
public static InputSource getInputSourceFromURI(String uri) {
return new InputSource(uri);
}
}
Streaming XML
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class MainClass {
public static void main(String[] args) throws Exception {
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL", "yourName", "mypwd");
Statement stmt = conn.createStatement();
String streamingDataSql = "CREATE TABLE XML_Data (id INTEGER, Data LONG)";
try {
stmt.executeUpdate("DROP TABLE XML_Data");
} catch (SQLException se) {
if (se.getErrorCode() == 942)
System.out.println("Error dropping XML_Data table:" + se.getMessage());
}
stmt.executeUpdate(streamingDataSql);
File f = new File("employee.xml");
long fileLength = f.length();
FileInputStream fis = new FileInputStream(f);
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO XML_Data VALUES (?,?)");
pstmt.setInt(1, 100);
pstmt.setAsciiStream(2, fis, (int) fileLength);
pstmt.execute();
fis.close();
ResultSet rset = stmt.executeQuery("SELECT Data FROM XML_Data WHERE id=100");
if (rset.next()) {
InputStream xmlInputStream = rset.getAsciiStream(1);
int c;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((c = xmlInputStream.read()) != -1)
bos.write(c);
System.out.println(bos.toString());
}
conn.close();
}
}
Utility class for working with xml data
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
/**
* Utility class for working with xml data
*
* Implementation is heavily based on org.apache.log4j.helpers.Transform
*
* @author The Apache MINA Project (dev@mina.apache.org)
* @version $Rev: 686610 $, $Date: 2008-08-17 15:31:25 +0200 (Sun, 17 Aug 2008) $
*/
public class Transform {
private static final String CDATA_START = "<![CDATA[";
private static final String CDATA_END = "]]>";
private static final String CDATA_PSEUDO_END = "]]>";
private static final String CDATA_EMBEDED_END = CDATA_END + CDATA_PSEUDO_END + CDATA_START;
private static final int CDATA_END_LEN = CDATA_END.length();
/**
* This method takes a string which may contain HTML tags (ie,
* <b>, <table>, etc) and replaces any
* "<", ">" , "&" or """
* characters with respective predefined entity references.
*
* @param input The text to be converted.
* @return The input string with the special characters replaced.
* */
static public String escapeTags(final String input) {
// Check if the string is null, zero length or devoid of special characters
// if so, return what was sent in.
if(input == null
|| input.length() == 0
|| (input.indexOf(""") == -1 &&
input.indexOf("&") == -1 &&
input.indexOf("<") == -1 &&
input.indexOf(">") == -1)) {
return input;
}
StringBuilder buf = new StringBuilder(input.length() + 6);
char ch;
int len = input.length();
for(int i=0; i < len; i++) {
ch = input.charAt(i);
if (ch > ">") {
buf.append(ch);
} else if(ch == "<") {
buf.append("<");
} else if(ch == ">") {
buf.append(">");
} else if(ch == "&") {
buf.append("&");
} else if(ch == """) {
buf.append(""");
} else {
buf.append(ch);
}
}
return buf.toString();
}
/**
* Ensures that embeded CDEnd strings (]]>) are handled properly
* within message, NDC and throwable tag text.
*
* @param buf StringBuffer holding the XML data to this point. The
* initial CDStart (<![CDATA[) and final CDEnd (]]>) of the CDATA
* section are the responsibility of the calling method.
* @param str The String that is inserted into an existing CDATA Section within buf.
* */
static public void appendEscapingCDATA(final StringBuffer buf,
final String str) {
if (str != null) {
int end = str.indexOf(CDATA_END);
if (end < 0) {
buf.append(str);
} else {
int start = 0;
while (end > -1) {
buf.append(str.substring(start, end));
buf.append(CDATA_EMBEDED_END);
start = end + CDATA_END_LEN;
if (start < str.length()) {
end = str.indexOf(CDATA_END, start);
} else {
return;
}
}
buf.append(str.substring(start));
}
}
}
/**
* convert a Throwable into an array of Strings
* @param throwable
* @return string representation of the throwable
*/
public static String[] getThrowableStrRep(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
throwable.printStackTrace(pw);
pw.flush();
LineNumberReader reader = new LineNumberReader(new StringReader(sw.toString()));
ArrayList<String> lines = new ArrayList<String>();
try {
String line = reader.readLine();
while(line != null) {
lines.add(line);
line = reader.readLine();
}
} catch(IOException ex) {
lines.add(ex.toString());
}
String[] rep = new String[lines.size()];
lines.toArray(rep);
return rep;
}
}
whether the given 32 bit character is a valid XML 1.1 character.
public class Utils {
/**
* Tests whether the given 32 bit character is a valid XML 1.1 character.
*/
public static boolean isXML11Character(int c) {
return c >= 1 && c <= 0xd7ff
|| c >= 0xe000 && c <= 0xfffd
|| c >= 0x10000 && c <= 0x10ffff;
}
}
Whether the given character is a valid XML space.
public class Utils {
/**
* Tests whether the given character is a valid space.
*/
public static boolean isXMLSpace(char c) {
return (c <= 0x0020) &&
(((((1L << 0x0009) |
(1L << 0x000A) |
(1L << 0x000D) |
(1L << 0x0020)) >> c) & 1L) != 0);
}
}
Your won XML binding
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class TestModelBuilder {
public static void main(String[] args) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
XMLReader parser = saxParser.getXMLReader();
SAXModelBuilder mb = new SAXModelBuilder();
parser.setContentHandler(mb);
parser.parse(new InputSource("zooinventory.xml"));
Element2 inventory = (Element2) mb.getModel();
System.out.println("Animals = " + inventory.getAnimals());
Element3 cocoa = (Element3) (inventory.getAnimals().get(1));
ElementA recipe = cocoa.getFoodRecipe();
System.out.println("Recipe = " + recipe);
}
}
class SimpleElement {
StringBuffer text = new StringBuffer();
public void addText(String s) {
text.append(s);
}
public String getText() {
return text.toString();
}
public void setAttributeValue(String name, String value) {
throw new Error(getClass() + ": No attributes allowed");
}
}
class ElementA extends SimpleElement {
String name;
List<String> values = new ArrayList<String>();
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void addIngredient(String ingredient) {
values.add(ingredient);
}
public void setValues(List<String> ingredients) {
this.values = ingredients;
}
public List<String> getIngredients() {
return values;
}
public String toString() {
return name + ": " + values.toString();
}
}
class Element2 extends SimpleElement {
List<Element3> value = new ArrayList<Element3>();
public void addAnimal(Element3 animal) {
value.add(animal);
}
public List<Element3> getAnimals() {
return value;
}
public void setValue(List<Element3> animals) {
this.value = animals;
}
}
class Element3 extends SimpleElement {
public final static int MAMMAL = 1;
int animalClass;
String tag1, tag2, tag3, tag4, tag5;
ElementA foodRecipe;
public void setTag1(String name) {
this.tag1 = name;
}
public String getName() {
return tag1;
}
public void setTag2(String species) {
this.tag2 = species;
}
public String getSpecies() {
return tag2;
}
public void setTag3(String habitat) {
this.tag3 = habitat;
}
public String getHabitat() {
return tag3;
}
public void setTag4(String food) {
this.tag4 = food;
}
public String getFood() {
return tag4;
}
public void setFoodRecipe(ElementA recipe) {
this.foodRecipe = recipe;
}
public ElementA getFoodRecipe() {
return foodRecipe;
}
public void setTag5(String temperament) {
this.tag5 = temperament;
}
public String getTemperament() {
return tag5;
}
public void setAnimalClass(int animalClass) {
this.animalClass = animalClass;
}
public int getAnimalClass() {
return animalClass;
}
public void setAttributeValue(String name, String value) {
if (name.equals("class") && value.equals("mammal"))
setAnimalClass(MAMMAL);
else
throw new Error("No such attribute: " + name);
}
public String toString() {
return tag1 + "(" + tag2 + ")";
}
}
class SAXModelBuilder extends DefaultHandler {
Stack<SimpleElement> stack = new Stack<SimpleElement>();
SimpleElement element;
public void startElement(String namespace, String localname, String qname, Attributes atts)
throws SAXException {
SimpleElement element = null;
try {
element = (SimpleElement) Class.forName(qname).newInstance();
} catch (Exception e) {
}
if (element == null)
element = new SimpleElement();
for (int i = 0; i < atts.getLength(); i++)
element.setAttributeValue(atts.getQName(i), atts.getValue(i));
stack.push(element);
}
public void endElement(String namespace, String localname, String qname) throws SAXException {
element = stack.pop();
if (!stack.empty())
try {
setProperty(qname, stack.peek(), element);
} catch (Exception e) {
throw new SAXException("Error: " + e);
}
}
public void characters(char[] ch, int start, int len) {
String text = new String(ch, start, len);
stack.peek().addText(text);
}
void setProperty(String name, Object target, Object value) throws SAXException {
Method method = null;
try {
method = target.getClass().getMethod("add" + name, value.getClass());
} catch (NoSuchMethodException e) {
}
if (method == null)
try {
method = target.getClass().getMethod("set" + name, value.getClass());
} catch (NoSuchMethodException e) {
}
if (method == null)
try {
value = ((SimpleElement) value).getText();
method = target.getClass().getMethod("add" + name, String.class);
} catch (NoSuchMethodException e) {
}
try {
if (method == null)
method = target.getClass().getMethod("set" + name, String.class);
method.invoke(target, value);
} catch (Exception e) {
throw new SAXException(e.toString());
}
}
public SimpleElement getModel() {
return element;
}
}
//File: zooinventory.xml
/*<?xml version="1.0" encoding="UTF-8"?>
<Element2>
<Element3 animalClass="mammal">
<Name>A</Name>
<Species>B</Species>
<Habitat>C</Habitat>
<Food>D</Food>
<Temperament>E</Temperament>
<Weight>1</Weight>
</Element3>
<Element3 animalClass="mammal">
<Name>F</Name>
<Species>G</Species>
<Habitat>H</Habitat>
<ElementA>
<Name>I</Name>
<Ingredient>I1</Ingredient>
<Ingredient>I2</Ingredient>
<Ingredient>I2</Ingredient>
</ElementA>
<Temperament>J</Temperament>
<Weight>4</Weight>
</Element3>
</Element2>
*/