@ -42,6 +42,9 @@ import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler ;
import org.xml.sax.ext.LexicalHandler ;
import org.xml.sax.helpers.XMLFilterImpl ;
import org.xml.sax.helpers.XMLFilterImpl ;
import static org.dom4j.util.StringUtils.endsWithWhitespace ;
import static org.dom4j.util.StringUtils.startsWithWhitespace ;
/ * *
/ * *
* < p >
* < p >
* < code > XMLWriter < / code > takes a DOM4J tree and formats it to a stream as
* < code > XMLWriter < / code > takes a DOM4J tree and formats it to a stream as
@ -54,7 +57,7 @@ import org.xml.sax.helpers.XMLFilterImpl;
* such as to allow suppression of the XML declaration , the encoding declaration
* such as to allow suppression of the XML declaration , the encoding declaration
* or whether empty documents are collapsed .
* or whether empty documents are collapsed .
* < / p >
* < / p >
*
*
* < p >
* < p >
* There are < code > write ( . . . ) < / code > methods to print any of the standard
* There are < code > write ( . . . ) < / code > methods to print any of the standard
* DOM4J classes , including < code > Document < / code > and < code > Element < / code > ,
* DOM4J classes , including < code > Document < / code > and < code > Element < / code > ,
@ -63,10 +66,10 @@ import org.xml.sax.helpers.XMLFilterImpl;
* preferred character encoding to be ignored . If you use encodings other than
* preferred character encoding to be ignored . If you use encodings other than
* UTF8 , we recommend using the method that takes an OutputStream instead .
* UTF8 , we recommend using the method that takes an OutputStream instead .
* < / p >
* < / p >
*
*
* @author < a href = "mailto:jstrachan@apache.org" > James Strachan < / a >
* @author < a href = "mailto:jstrachan@apache.org" > James Strachan < / a >
* @author Joseph Bowbeer
* @author Joseph Bowbeer
* @version $Revision$
* @version $Revision : 1 . 83 $
* /
* /
public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
private static final String PAD_TEXT = " " ;
private static final String PAD_TEXT = " " ;
@ -139,7 +142,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
private boolean inDTD ;
private boolean inDTD ;
/** The namespaces used for the current element when consuming SAX events */
/** The namespaces used for the current element when consuming SAX events */
private Map namespacesMap ;
private Map < String , String > namespacesMap ;
/ * *
/ * *
* what is the maximum allowed character code such as 127 in US - ASCII ( 7
* what is the maximum allowed character code such as 127 in US - ASCII ( 7
@ -200,7 +203,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* DOCUMENT ME !
* DOCUMENT ME !
*
*
* @return true if text thats output should be escaped . This is enabled by
* @return true if text thats output should be escaped . This is enabled by
* default . It could be disabled if the output format is textual ,
* default . It could be disabled if the output format is textual ,
* like in XSLT where we can have xml , html or text output .
* like in XSLT where we can have xml , html or text output .
@ -213,7 +216,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* Sets whether text output should be escaped or not . This is enabled by
* Sets whether text output should be escaped or not . This is enabled by
* default . It could be disabled if the output format is textual , like in
* default . It could be disabled if the output format is textual , like in
* XSLT where we can have xml , html or text output .
* XSLT where we can have xml , html or text output .
*
*
* @param escapeText
* @param escapeText
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -225,7 +228,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* Set the initial indentation level . This can be used to output a document
* Set the initial indentation level . This can be used to output a document
* ( or , more likely , an element ) starting at a given indent level , so it ' s
* ( or , more likely , an element ) starting at a given indent level , so it ' s
* not always flush against the left margin . Default : 0
* not always flush against the left margin . Default : 0
*
*
* @param indentLevel
* @param indentLevel
* the number of indents to start with
* the number of indents to start with
* /
* /
@ -237,7 +240,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* Returns the maximum allowed character code that should be allowed
* Returns the maximum allowed character code that should be allowed
* unescaped which defaults to 127 in US - ASCII ( 7 bit ) or 255 in ISO - ( 8
* unescaped which defaults to 127 in US - ASCII ( 7 bit ) or 255 in ISO - ( 8
* bit ) .
* bit ) .
*
*
* @return DOCUMENT ME !
* @return DOCUMENT ME !
* /
* /
public int getMaximumAllowedCharacter ( ) {
public int getMaximumAllowedCharacter ( ) {
@ -254,7 +257,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* escape any characters ( other than the special XML characters like & lt ;
* escape any characters ( other than the special XML characters like & lt ;
* & gt ; & amp ; ) If this is not explicitly set then it is defaulted from the
* & gt ; & amp ; ) If this is not explicitly set then it is defaulted from the
* encoding .
* encoding .
*
*
* @param maximumAllowedCharacter
* @param maximumAllowedCharacter
* The maximumAllowedCharacter to set
* The maximumAllowedCharacter to set
* /
* /
@ -264,7 +267,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Flushes the underlying Writer
* Flushes the underlying Writer
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -274,7 +277,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Closes the underlying Writer
* Closes the underlying Writer
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -284,7 +287,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the new line text to the underlying Writer
* Writes the new line text to the underlying Writer
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -294,10 +297,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the given { @link Attribute } .
* Writes the given { @link Attribute } .
*
*
* @param attribute
* @param attribute
* < code > Attribute < / code > to output .
* < code > Attribute < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -313,21 +316,21 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* < p >
* < p >
* This will print the < code > Document < / code > to the current Writer .
* This will print the < code > Document < / code > to the current Writer .
* < / p >
* < / p >
*
*
* < p >
* < p >
* Warning : using your own Writer may cause the writer ' s preferred character
* Warning : using your own Writer may cause the writer ' s preferred character
* encoding to be ignored . If you use encodings other than UTF8 , we
* encoding to be ignored . If you use encodings other than UTF8 , we
* recommend using the method that takes an OutputStream instead .
* recommend using the method that takes an OutputStream instead .
* < / p >
* < / p >
*
*
* < p >
* < p >
* Note : as with all Writers , you may need to flush ( ) yours after this
* Note : as with all Writers , you may need to flush ( ) yours after this
* method returns .
* method returns .
* < / p >
* < / p >
*
*
* @param doc
* @param doc
* < code > Document < / code > to format .
* < code > Document < / code > to format .
*
*
* @throws IOException
* @throws IOException
* if there ' s any problem writing .
* if there ' s any problem writing .
* /
* /
@ -358,10 +361,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* s , and its value , and all its content ( child nodes ) to the current
* s , and its value , and all its content ( child nodes ) to the current
* Writer .
* Writer .
* < / p >
* < / p >
*
*
* @param element
* @param element
* < code > Element < / code > to output .
* < code > Element < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -375,10 +378,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the given { @link CDATA } .
* Writes the given { @link CDATA } .
*
*
* @param cdata
* @param cdata
* < code > CDATA < / code > to output .
* < code > CDATA < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -392,10 +395,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the given { @link Comment } .
* Writes the given { @link Comment } .
*
*
* @param comment
* @param comment
* < code > Comment < / code > to output .
* < code > Comment < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -409,10 +412,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the given { @link DocumentType } .
* Writes the given { @link DocumentType } .
*
*
* @param docType
* @param docType
* < code > DocumentType < / code > to output .
* < code > DocumentType < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -426,10 +429,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the given { @link Entity } .
* Writes the given { @link Entity } .
*
*
* @param entity
* @param entity
* < code > Entity < / code > to output .
* < code > Entity < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -443,10 +446,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the given { @link Namespace } .
* Writes the given { @link Namespace } .
*
*
* @param namespace
* @param namespace
* < code > Namespace < / code > to output .
* < code > Namespace < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -460,10 +463,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the given { @link ProcessingInstruction } .
* Writes the given { @link ProcessingInstruction } .
*
*
* @param processingInstruction
* @param processingInstruction
* < code > ProcessingInstruction < / code > to output .
* < code > ProcessingInstruction < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -481,10 +484,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* Print out a { @link String } , Perfoms the necessary entity escaping and
* Print out a { @link String } , Perfoms the necessary entity escaping and
* whitespace stripping .
* whitespace stripping .
* < / p >
* < / p >
*
*
* @param text
* @param text
* is the text to output
* is the text to output
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -498,10 +501,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the given { @link Text } .
* Writes the given { @link Text } .
*
*
* @param text
* @param text
* < code > Text < / code > to output .
* < code > Text < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -515,10 +518,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the given { @link Node } .
* Writes the given { @link Node } .
*
*
* @param node
* @param node
* < code > Node < / code > to output .
* < code > Node < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -533,10 +536,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the given object which should be a String , a Node or a List of
* Writes the given object which should be a String , a Node or a List of
* Nodes .
* Nodes .
*
*
* @param object
* @param object
* is the object to output .
* is the object to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -546,10 +549,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
} else if ( object instanceof String ) {
} else if ( object instanceof String ) {
write ( ( String ) object ) ;
write ( ( String ) object ) ;
} else if ( object instanceof List ) {
} else if ( object instanceof List ) {
List list = ( List ) object ;
List < ? > list = ( List < ? > ) object ;
for ( int i = 0 , size = list . size ( ) ; i < size ; i + + ) {
for ( Object aList : list ) {
write ( list . get ( i ) ) ;
write ( aList ) ;
}
}
} else if ( object ! = null ) {
} else if ( object ! = null ) {
throw new IOException ( "Invalid object: " + object ) ;
throw new IOException ( "Invalid object: " + object ) ;
@ -561,16 +564,17 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* Writes the opening tag of an { @link Element } , including its { @link
* Writes the opening tag of an { @link Element } , including its { @link
* Attribute } s but without its content .
* Attribute } s but without its content .
* < / p >
* < / p >
*
*
* @param element
* @param element
* < code > Element < / code > to output .
* < code > Element < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
public void writeOpen ( Element element ) throws IOException {
public void writeOpen ( Element element ) throws IOException {
writer . write ( "<" ) ;
writer . write ( "<" ) ;
writer . write ( element . getQualifiedName ( ) ) ;
writer . write ( element . getQualifiedName ( ) ) ;
writeNamespaces ( element ) ;
writeAttributes ( element ) ;
writeAttributes ( element ) ;
writer . write ( ">" ) ;
writer . write ( ">" ) ;
}
}
@ -579,10 +583,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* < p >
* < p >
* Writes the closing tag of an { @link Element }
* Writes the closing tag of an { @link Element }
* < / p >
* < / p >
*
*
* @param element
* @param element
* < code > Element < / code > to output .
* < code > Element < / code > to output .
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -599,8 +603,8 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
public void setProperty ( String name , Object value )
public void setProperty ( String name , Object value )
throws SAXNotRecognizedException , SAXNotSupportedException {
throws SAXNotRecognizedException , SAXNotSupportedException {
for ( int i = 0 ; i < LEXICAL_HANDLER_NAMES . length ; i + + ) {
for ( String lexicalHandlerName : LEXICAL_HANDLER_NAMES ) {
if ( LEXICAL_HANDLER_NAMES [ i ] . equals ( name ) ) {
if ( lexicalHandlerName . equals ( name ) ) {
setLexicalHandler ( ( LexicalHandler ) value ) ;
setLexicalHandler ( ( LexicalHandler ) value ) ;
return ;
return ;
@ -612,8 +616,8 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
public Object getProperty ( String name ) throws SAXNotRecognizedException ,
public Object getProperty ( String name ) throws SAXNotRecognizedException ,
SAXNotSupportedException {
SAXNotSupportedException {
for ( int i = 0 ; i < LEXICAL_HANDLER_NAMES . length ; i + + ) {
for ( String lexicalHandlerName : LEXICAL_HANDLER_NAMES ) {
if ( LEXICAL_HANDLER_NAMES [ i ] . equals ( name ) ) {
if ( lexicalHandlerName . equals ( name ) ) {
return getLexicalHandler ( ) ;
return getLexicalHandler ( ) ;
}
}
}
}
@ -662,7 +666,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
public void startPrefixMapping ( String prefix , String uri )
public void startPrefixMapping ( String prefix , String uri )
throws SAXException {
throws SAXException {
if ( namespacesMap = = null ) {
if ( namespacesMap = = null ) {
namespacesMap = new HashMap ( ) ;
namespacesMap = new HashMap < String , String > ( ) ;
}
}
namespacesMap . put ( prefix , uri ) ;
namespacesMap . put ( prefix , uri ) ;
@ -975,10 +979,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Determines if element is a special case of XML elements where it contains
* Determines if element is a special case of XML elements where it contains
* an xml : space attribute of "preserve" . If it does , then retain whitespace .
* an xml : space attribute of "preserve" . If it does , then retain whitespace .
*
*
* @param element
* @param element
* DOCUMENT ME !
* DOCUMENT ME !
*
*
* @return DOCUMENT ME !
* @return DOCUMENT ME !
* /
* /
protected final boolean isElementSpacePreserved ( Element element ) {
protected final boolean isElementSpacePreserved ( Element element ) {
@ -986,12 +990,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
boolean preserveFound = preserve ; // default to global state
boolean preserveFound = preserve ; // default to global state
if ( attr ! = null ) {
if ( attr ! = null ) {
if ( "xml" . equals ( attr . getNamespacePrefix ( ) )
preserveFound = "xml" . equals ( attr . getNamespacePrefix ( ) ) & & "preserve" . equals ( attr . getText ( ) ) ;
& & "preserve" . equals ( attr . getText ( ) ) ) {
preserveFound = true ;
} else {
preserveFound = false ;
}
}
}
return preserveFound ;
return preserveFound ;
@ -1003,10 +1002,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* whitespace trimming occurs to avoid problems with multiple text nodes
* whitespace trimming occurs to avoid problems with multiple text nodes
* being created due to text content that spans parser buffers in a SAX
* being created due to text content that spans parser buffers in a SAX
* parser .
* parser .
*
*
* @param element
* @param element
* DOCUMENT ME !
* DOCUMENT ME !
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -1023,34 +1022,34 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
// concatenate adjacent text nodes together
// concatenate adjacent text nodes together
// so that whitespace trimming works properly
// so that whitespace trimming works properly
Text lastTextNode = null ;
Text lastTextNode = null ;
StringBuff er buff = null ;
StringBuild er buff = null ;
boolean textOnly = true ;
boolean textOnly = true ;
for ( int i = 0 , size = element . nodeCount ( ) ; i < size ; i + + ) {
for ( Node node : element . content ( ) ) {
Node node = element . node ( i ) ;
if ( node instanceof Text ) {
if ( node instanceof Text ) {
if ( lastTextNode = = null ) {
if ( lastTextNode = = null ) {
lastTextNode = ( Text ) node ;
lastTextNode = ( Text ) node ;
} else {
} else {
if ( buff = = null ) {
if ( buff = = null ) {
buff = new StringBuff er ( lastTextNode . getText ( ) ) ;
buff = new StringBuild er ( lastTextNode . getText ( ) ) ;
}
}
buff . append ( ( ( Text ) node ) . getText ( ) ) ;
buff . append ( ( node ) . getText ( ) ) ;
}
}
} else {
} else {
if ( ! textOnly & & format . isPadText ( ) ) {
if ( ! textOnly & & format . isPadText ( ) ) {
// only add the PAD_TEXT if the text itself starts with
// only add the PAD_TEXT if the text itself starts with
// whitespace
// whitespace
char firstChar = 'a' ;
final boolean startsWithWhitespace ;
if ( buff ! = null ) {
if ( buff ! = null ) {
firstChar = buff . charAt ( 0 ) ;
startsWithWhitespace = startsWithWhitespace ( buff ) ;
} else if ( lastTextNode ! = null ) {
} else if ( lastTextNode ! = null ) {
firstChar = lastTextNode . getText ( ) . charAt ( 0 ) ;
startsWithWhitespace = startsWithWhitespace ( lastTextNode . getText ( ) ) ;
} else {
startsWithWhitespace = false ;
}
}
if ( Character . isWhitespace ( firstChar ) ) {
if ( startsWithWhitespace ) {
writer . write ( PAD_TEXT ) ;
writer . write ( PAD_TEXT ) ;
}
}
}
}
@ -1066,15 +1065,14 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
if ( format . isPadText ( ) ) {
if ( format . isPadText ( ) ) {
// only add the PAD_TEXT if the text itself ends
// only add the PAD_TEXT if the text itself ends
// with whitespace
// with whitespace
char lastTextChar = 'a' ;
final boolean endsWithWhitespace ;
if ( buff ! = null ) {
if ( buff ! = null ) {
lastTextChar = buff . charAt ( buff . length ( ) - 1 ) ;
endsWithWhitespace = endsWithWhitespace ( buff ) ;
} else if ( lastTextNode ! = null ) {
} else {
String txt = lastTextNode . getText ( ) ;
endsWithWhitespace = endsWithWhitespace ( lastTextNode . getText ( ) ) ;
lastTextChar = txt . charAt ( txt . length ( ) - 1 ) ;
}
}
if ( Character . isWhitespace ( lastTextChar ) ) {
if ( endsWithWhitespace ) {
writer . write ( PAD_TEXT ) ;
writer . write ( PAD_TEXT ) ;
}
}
}
}
@ -1091,14 +1089,14 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
if ( ! textOnly & & format . isPadText ( ) ) {
if ( ! textOnly & & format . isPadText ( ) ) {
// only add the PAD_TEXT if the text itself starts with
// only add the PAD_TEXT if the text itself starts with
// whitespace
// whitespace
char firstChar = 'a' ;
final boolean startsWithWhitespace ;
if ( buff ! = null ) {
if ( buff ! = null ) {
firstChar = buff . charAt ( 0 ) ;
startsWithWhitespace = startsWithWhitespace ( buff ) ;
} else {
} else {
firstChar = lastTextNode . getText ( ) . charAt ( 0 ) ;
startsWithWhitespace = startsWithWhitespace ( lastTextNode . getText ( ) ) ;
}
}
if ( Character . isWhitespace ( firstChar ) ) {
if ( startsWithWhitespace ) {
writer . write ( PAD_TEXT ) ;
writer . write ( PAD_TEXT ) ;
}
}
}
}
@ -1115,9 +1113,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
} else {
} else {
Node lastTextNode = null ;
Node lastTextNode = null ;
for ( int i = 0 , size = element . nodeCount ( ) ; i < size ; i + + ) {
for ( Node node : element . content ( ) ) {
Node node = element . node ( i ) ;
if ( node instanceof Text ) {
if ( node instanceof Text ) {
writeNode ( node ) ;
writeNode ( node ) ;
lastTextNode = node ;
lastTextNode = node ;
@ -1125,10 +1121,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
if ( ( lastTextNode ! = null ) & & format . isPadText ( ) ) {
if ( ( lastTextNode ! = null ) & & format . isPadText ( ) ) {
// only add the PAD_TEXT if the text itself ends with
// only add the PAD_TEXT if the text itself ends with
// whitespace
// whitespace
String txt = lastTextNode . getText ( ) ;
if ( endsWithWhitespace ( lastTextNode . getText ( ) ) ) {
char lastTextChar = txt . charAt ( txt . length ( ) - 1 ) ;
if ( Character . isWhitespace ( lastTextChar ) ) {
writer . write ( PAD_TEXT ) ;
writer . write ( PAD_TEXT ) ;
}
}
}
}
@ -1174,17 +1167,15 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the SAX namepsaces
* Writes the SAX namepsaces
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
protected void writeNamespaces ( ) throws IOException {
protected void writeNamespaces ( ) throws IOException {
if ( namespacesMap ! = null ) {
if ( namespacesMap ! = null ) {
for ( Iterator iter = namespacesMap . entrySet ( ) . iterator ( ) ; iter
for ( Map . Entry < String , String > entry : namespacesMap . entrySet ( ) ) {
. hasNext ( ) ; ) {
String prefix = entry . getKey ( ) ;
Map . Entry entry = ( Map . Entry ) iter . next ( ) ;
String uri = entry . getValue ( ) ;
String prefix = ( String ) entry . getKey ( ) ;
String uri = ( String ) entry . getValue ( ) ;
writeNamespace ( prefix , uri ) ;
writeNamespace ( prefix , uri ) ;
}
}
@ -1194,15 +1185,15 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the SAX namepsaces
* Writes the SAX namepsaces
*
*
* @param prefix
* @param prefix
* the prefix
* the prefix
* @param uri
* @param uri
* the namespace uri
* the namespace uri
*
*
* @throws IOException
* @throws IOException DOCUMENT ME !
* /
* /
protected void writeNamespace ( String prefix , String uri )
protected void writeNamespace ( String prefix , String uri )
throws IOException {
throws IOException {
if ( ( prefix ! = null ) & & ( prefix . length ( ) > 0 ) ) {
if ( ( prefix ! = null ) & & ( prefix . length ( ) > 0 ) ) {
writer . write ( " xmlns:" ) ;
writer . write ( " xmlns:" ) ;
@ -1216,6 +1207,19 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
writer . write ( "\"" ) ;
writer . write ( "\"" ) ;
}
}
/ * *
* Writes all namespaces declared directly on element .
*
* @throws IOException
* /
protected void writeNamespaces ( Element element ) throws IOException {
assert element ! = null ;
for ( Namespace ns : element . declaredNamespaces ( ) ) {
writeNamespace ( ns ) ;
namespaceStack . push ( ns ) ;
}
}
protected void writeProcessingInstruction ( ProcessingInstruction pi )
protected void writeProcessingInstruction ( ProcessingInstruction pi )
throws IOException {
throws IOException {
// indent();
// indent();
@ -1259,12 +1263,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
writer . write ( token ) ;
writer . write ( token ) ;
lastOutputNodeType = Node . TEXT_NODE ;
lastOutputNodeType = Node . TEXT_NODE ;
lastChar = token . charAt ( token . length ( ) - 1 ) ;
}
}
} else {
} else {
lastOutputNodeType = Node . TEXT_NODE ;
lastOutputNodeType = Node . TEXT_NODE ;
writer . write ( text ) ;
writer . write ( text ) ;
lastChar = text . charAt ( text . length ( ) - 1 ) ;
}
}
}
}
}
}
@ -1272,10 +1274,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* This method is used to write out Nodes that contain text and still allow
* This method is used to write out Nodes that contain text and still allow
* for xml : space to be handled properly .
* for xml : space to be handled properly .
*
*
* @param node
* @param node
* DOCUMENT ME !
* DOCUMENT ME !
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -1289,7 +1291,6 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
lastOutputNodeType = Node . TEXT_NODE ;
lastOutputNodeType = Node . TEXT_NODE ;
writer . write ( text ) ;
writer . write ( text ) ;
lastChar = text . charAt ( text . length ( ) - 1 ) ;
}
}
}
}
@ -1362,9 +1363,9 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
}
}
// try to register for lexical events
// try to register for lexical events
for ( int i = 0 ; i < LEXICAL_HANDLER_NAMES . length ; i + + ) {
for ( String lexicalHandlerName : LEXICAL_HANDLER_NAMES ) {
try {
try {
parent . setProperty ( LEXICAL_HANDLER_NAMES [ i ] , this ) ;
parent . setProperty ( lexicalHandlerName , this ) ;
break ;
break ;
} catch ( SAXNotRecognizedException ex ) {
} catch ( SAXNotRecognizedException ex ) {
@ -1434,10 +1435,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Writes the attributes of the given element
* Writes the attributes of the given element
*
*
* @param element
* @param element
* DOCUMENT ME !
* DOCUMENT ME !
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -1481,26 +1482,24 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
writeNamespace ( null , uri ) ;
writeNamespace ( null , uri ) ;
}
}
} else {
} else {
char quote = format . getAttributeQuoteCharacter ( ) ;
writeAttribute ( attribute ) ;
writer . write ( " " ) ;
writer . write ( attribute . getQualifiedName ( ) ) ;
writer . write ( "=" ) ;
writer . write ( quote ) ;
writeEscapeAttributeEntities ( attribute . getValue ( ) ) ;
writer . write ( quote ) ;
}
}
}
}
}
}
protected void writeAttribute ( Attribute attribute ) throws IOException {
protected void writeAttribute ( Attribute attribute ) throws IOException {
writeAttribute ( attribute . getQualifiedName ( ) , attribute . getValue ( ) ) ;
}
protected void writeAttribute ( String qualifiedName , String value ) throws IOException {
writer . write ( " " ) ;
writer . write ( " " ) ;
writer . write ( attribute . getQualifiedName ( ) ) ;
writer . write ( qualifiedName ) ;
writer . write ( "=" ) ;
writer . write ( "=" ) ;
char quote = format . getAttributeQuoteCharacter ( ) ;
char quote = format . getAttributeQuoteCharacter ( ) ;
writer . write ( quote ) ;
writer . write ( quote ) ;
writeEscapeAttributeEntities ( attribute . getValue ( ) ) ;
writeEscapeAttributeEntities ( value ) ;
writer . write ( quote ) ;
writer . write ( quote ) ;
lastOutputNodeType = Node . ATTRIBUTE_NODE ;
lastOutputNodeType = Node . ATTRIBUTE_NODE ;
@ -1514,13 +1513,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
protected void writeAttribute ( Attributes attributes , int index )
protected void writeAttribute ( Attributes attributes , int index )
throws IOException {
throws IOException {
char quote = format . getAttributeQuoteCharacter ( ) ;
writeAttribute ( attributes . getQName ( index ) , attributes . getValue ( index ) ) ;
writer . write ( " " ) ;
writer . write ( attributes . getQName ( index ) ) ;
writer . write ( "=" ) ;
writer . write ( quote ) ;
writeEscapeAttributeEntities ( attributes . getValue ( index ) ) ;
writer . write ( quote ) ;
}
}
protected void indent ( ) throws IOException {
protected void indent ( ) throws IOException {
@ -1537,29 +1530,26 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* < p >
* < p >
* This will print a new line only if the newlines flag was set to true
* This will print a new line only if the newlines flag was set to true
* < / p >
* < / p >
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
protected void writePrintln ( ) throws IOException {
protected void writePrintln ( ) throws IOException {
if ( format . isNewlines ( ) ) {
if ( format . isNewlines ( ) ) {
String seperator = format . getLineSeparator ( ) ;
writer . write ( format . getLineSeparator ( ) ) ;
if ( lastChar ! = seperator . charAt ( seperator . length ( ) - 1 ) ) {
writer . write ( format . getLineSeparator ( ) ) ;
}
}
}
}
}
/ * *
/ * *
* Get an OutputStreamWriter , use preferred encoding .
* Get an OutputStreamWriter , use preferred encoding .
*
*
* @param outStream
* @param outStream
* DOCUMENT ME !
* DOCUMENT ME !
* @param encoding
* @param encoding
* DOCUMENT ME !
* DOCUMENT ME !
*
*
* @return DOCUMENT ME !
* @return DOCUMENT ME !
*
*
* @throws UnsupportedEncodingException
* @throws UnsupportedEncodingException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -1573,7 +1563,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* This will write the declaration to the given Writer . Assumes XML version
* This will write the declaration to the given Writer . Assumes XML version
* 1 . 0 since we don ' t directly know .
* 1 . 0 since we don ' t directly know .
* < / p >
* < / p >
*
*
* @throws IOException
* @throws IOException
* DOCUMENT ME !
* DOCUMENT ME !
* /
* /
@ -1633,10 +1623,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* This will take the pre - defined entities in XML 1 . 0 and convert their
* This will take the pre - defined entities in XML 1 . 0 and convert their
* character representation to the appropriate entity reference , suitable
* character representation to the appropriate entity reference , suitable
* for XML attributes .
* for XML attributes .
*
*
* @param text
* @param text
* DOCUMENT ME !
* DOCUMENT ME !
*
*
* @return DOCUMENT ME !
* @return DOCUMENT ME !
* /
* /
protected String escapeElementEntities ( String text ) {
protected String escapeElementEntities ( String text ) {
@ -1647,44 +1637,37 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
for ( i = 0 ; i < size ; i + + ) {
for ( i = 0 ; i < size ; i + + ) {
String entity = null ;
String entity = null ;
char c = text . charAt ( i ) ;
int c = text . codePointAt ( i ) ;
switch ( c ) {
switch ( c ) {
case '<' :
case '<' :
entity = "<" ;
entity = "<" ;
break ;
break ;
case '>' :
case '>' :
entity = ">" ;
entity = ">" ;
break ;
break ;
case '&' :
case '&' :
entity = "&" ;
entity = "&" ;
break ;
break ;
case '\t' :
case '\t' :
case '\n' :
case '\n' :
case '\r' :
case '\r' :
// don't encode standard whitespace characters
// don't encode standard whitespace characters
if ( preserve ) {
if ( preserve ) {
entity = String . valueOf ( c ) ;
entity = String . valueOf ( ( char ) c ) ;
}
}
break ;
break ;
default :
default :
if ( ( c < 32 ) | | shouldEncodeChar ( c ) ) {
if ( ( c < 32 ) | | shouldEncodeChar ( c ) ) {
entity = "&#" + ( int ) c + ";" ;
entity = "&#" + c + ";" ;
}
}
break ;
break ;
}
}
if ( entity ! = null ) {
if ( entity ! = null ) {
if ( block = = null ) {
if ( block = = null ) {
block = text . toCharArray ( ) ;
block = text . toCharArray ( ) ;
@ -1693,6 +1676,12 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
buffer . append ( block , last , i - last ) ;
buffer . append ( block , last , i - last ) ;
buffer . append ( entity ) ;
buffer . append ( entity ) ;
last = i + 1 ;
last = i + 1 ;
if ( Character . isSupplementaryCodePoint ( c ) ) {
last + + ;
}
}
if ( Character . isSupplementaryCodePoint ( c ) ) {
i + + ;
}
}
}
}
@ -1725,10 +1714,10 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* This will take the pre - defined entities in XML 1 . 0 and convert their
* This will take the pre - defined entities in XML 1 . 0 and convert their
* character representation to the appropriate entity reference , suitable
* character representation to the appropriate entity reference , suitable
* for XML attributes .
* for XML attributes .
*
*
* @param text
* @param text
* DOCUMENT ME !
* DOCUMENT ME !
*
*
* @return DOCUMENT ME !
* @return DOCUMENT ME !
* /
* /
protected String escapeAttributeEntities ( String text ) {
protected String escapeAttributeEntities ( String text ) {
@ -1741,53 +1730,37 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
for ( i = 0 ; i < size ; i + + ) {
for ( i = 0 ; i < size ; i + + ) {
String entity = null ;
String entity = null ;
char c = text . char At ( i ) ;
int c = text . codePoint At ( i ) ;
switch ( c ) {
switch ( c ) {
case '<' :
case '<' :
entity = "<" ;
entity = "<" ;
break ;
break ;
case '>' :
case '>' :
entity = ">" ;
entity = ">" ;
break ;
break ;
case '\'' :
case '\'' :
if ( quote = = '\'' ) {
if ( quote = = '\'' ) {
entity = "'" ;
entity = "'" ;
}
}
break ;
break ;
case '\"' :
case '\"' :
if ( quote = = '\"' ) {
if ( quote = = '\"' ) {
entity = """ ;
entity = """ ;
}
}
break ;
break ;
case '&' :
case '&' :
entity = "&" ;
entity = "&" ;
break ;
break ;
case '\t' :
case '\t' :
case '\n' :
case '\n' :
case '\r' :
case '\r' :
// don't encode standard whitespace characters
// don't encode standard whitespace characters
break ;
break ;
default :
default :
if ( ( c < 32 ) | | shouldEncodeChar ( c ) ) {
if ( ( c < 32 ) | | shouldEncodeChar ( c ) ) {
entity = "&#" + ( int ) c + ";" ;
entity = "&#" + c + ";" ;
}
}
break ;
break ;
}
}
@ -1799,6 +1772,12 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
buffer . append ( block , last , i - last ) ;
buffer . append ( block , last , i - last ) ;
buffer . append ( entity ) ;
buffer . append ( entity ) ;
last = i + 1 ;
last = i + 1 ;
if ( Character . isSupplementaryCodePoint ( c ) ) {
last + + ;
}
}
if ( Character . isSupplementaryCodePoint ( c ) ) {
i + + ;
}
}
}
}
@ -1823,23 +1802,23 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
/ * *
/ * *
* Should the given character be escaped . This depends on the encoding of
* Should the given character be escaped . This depends on the encoding of
* the document .
* the document .
*
*
* @param c
* @param codepoint Unicode codepoint .
* DOCUMENT ME !
* DOCUMENT ME !
*
*
* @return boolean
* @return boolean
* /
* /
protected boolean shouldEncodeChar ( char c ) {
protected boolean shouldEncodeChar ( int codepoint ) {
int max = getMaximumAllowedCharacter ( ) ;
int max = getMaximumAllowedCharacter ( ) ;
return ( max > 0 ) & & ( c > max ) ;
return ( max > 0 ) & & ( codepoint > max ) ;
}
}
/ * *
/ * *
* Returns the maximum allowed character code that should be allowed
* Returns the maximum allowed character code that should be allowed
* unescaped which defaults to 127 in US - ASCII ( 7 bit ) or 255 in ISO - ( 8
* unescaped which defaults to 127 in US - ASCII ( 7 bit ) or 255 in ISO - ( 8
* bit ) .
* bit ) .
*
*
* @return DOCUMENT ME !
* @return DOCUMENT ME !
* /
* /
protected int defaultMaximumAllowedCharacter ( ) {
protected int defaultMaximumAllowedCharacter ( ) {
@ -1880,7 +1859,7 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* setTrimText , setNewLines , etc . Put in to support the HTMLWriter , in the
* setTrimText , setNewLines , etc . Put in to support the HTMLWriter , in the
* way that it pushes the current newline / trim state onto a stack and
* way that it pushes the current newline / trim state onto a stack and
* overrides the state within preformatted tags .
* overrides the state within preformatted tags .
*
*
* @return DOCUMENT ME !
* @return DOCUMENT ME !
* /
* /
protected OutputFormat getOutputFormat ( ) {
protected OutputFormat getOutputFormat ( ) {
@ -1900,24 +1879,24 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* Redistribution and use of this software and associated documentation
* Redistribution and use of this software and associated documentation
* ( "Software" ) , with or without modification , are permitted provided that the
* ( "Software" ) , with or without modification , are permitted provided that the
* following conditions are met :
* following conditions are met :
*
*
* 1 . Redistributions of source code must retain copyright statements and
* 1 . Redistributions of source code must retain copyright statements and
* notices . Redistributions must also contain a copy of this document .
* notices . Redistributions must also contain a copy of this document .
*
*
* 2 . Redistributions in binary form must reproduce the above copyright notice ,
* 2 . Redistributions in binary form must reproduce the above copyright notice ,
* this list of conditions and the following disclaimer in the documentation
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution .
* and / or other materials provided with the distribution .
*
*
* 3 . The name "DOM4J" must not be used to endorse or promote products derived
* 3 . The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff , Ltd . For
* from this Software without prior written permission of MetaStuff , Ltd . For
* written permission , please contact dom4j - info @metastuff.com.
* written permission , please contact dom4j - info @metastuff.com.
*
*
* 4 . Products derived from this Software may not be called "DOM4J" nor may
* 4 . Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff ,
* "DOM4J" appear in their names without prior written permission of MetaStuff ,
* Ltd . DOM4J is a registered trademark of MetaStuff , Ltd .
* Ltd . DOM4J is a registered trademark of MetaStuff , Ltd .
*
*
* 5 . Due credit should be given to the DOM4J Project - http : //www.dom4j.org
* 5 . Due credit should be given to the DOM4J Project - http : //www.dom4j.org
*
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF , LTD . AND CONTRIBUTORS ` ` AS IS ' ' AND
* THIS SOFTWARE IS PROVIDED BY METASTUFF , LTD . AND CONTRIBUTORS ` ` AS IS ' ' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* ANY EXPRESSED OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -1929,6 +1908,6 @@ public class XMLWriter extends XMLFilterImpl implements LexicalHandler {
* CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE )
* CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE )
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE .
* POSSIBILITY OF SUCH DAMAGE .
*
*
* Copyright 2001 - 2005 ( C ) MetaStuff , Ltd . All Rights Reserved .
* Copyright 2001 - 2005 ( C ) MetaStuff , Ltd . All Rights Reserved .
* /
* /