I found a solution:
to make a formated svg string from DOM
String svgStr = "";
try
{
StringWriter strW = new StringWriter();
SVGDOMPrettyPrinter pp = new SVGDOMPrettyPrinter();
pp.print(svgDoc, strW);
svgStr = strW.toString();
strW.flush();
strW.close();
}
catch (IOException exp)
{
exp.printStackTrace();
}
catch (TranscoderException e)
{
e.printStackTrace();
}
Now in svgStr there is an svg formated and tabulated String.
Here the SVGDOMPrettyPrinter class
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import org.w3c.dom.*;
import org.w3c.dom.svg.*;
import org.apache.batik.transcoder.ErrorHandler;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.util.SVGConstants;
import org.apache.batik.xml.XMLUtilities;
/** This class represents an SVGDOM to source files pretty-printer.
* Most of the code here is adapted from batik svg2svg Transcoder
* and DOMUtilities.
*
*/
public class SVGDOMPrettyPrinter {
/**
* The writer used to output the document.
*/
protected Writer writer;
/**
* The newline characters.
*/
protected String newline = "\n";
/**
* Whether the output must be formatted.
*/
protected boolean format = true;
/**
* The tabulation width.
*/
protected int tabulationWidth = 3;
/**
* The document width.
*/
protected int documentWidth = 300;
/**
* The public id.
*/
protected String publicId;
/**
* The system id.
*/
protected String systemId;
/**
* The XML declaration.
*/
protected String xmlDeclaration;
/**
* The type of the current lexical unit.
*/
protected int type;
/**
* The indentation level.
*/
protected int level;
/**
* The margin.
*/
protected StringBuffer margin = new StringBuffer();
/**
* The current line.
*/
protected int line = 1;
/**
* The current column.
*/
protected int column;
/**
* Whether the next markup can be indented.
*/
protected boolean canIndent = true;
/** Creates a new instance of DOMPrettyPrinter */
public SVGDOMPrettyPrinter() {
}
/**
* Sets the XML declaration text.
*/
public void setXMLDeclaration(String s) {
xmlDeclaration = s;
}
/**
* Sets the public ID.
*/
public void setPublicId(String s) {
publicId = s;
}
/**
* Sets the system ID.
*/
public void setSystemId(String s) {
systemId = s;
}
/**
* Sets the newline characters.
*/
public void setNewline(String s) {
newline = s;
}
/**
* Returns the newline characters.
*/
public String getNewline() {
return newline;
}
/**
* Sets the format attribute.
*/
public void setFormat(boolean b) {
format = b;
}
/**
* Returns whether the output must be formatted.
*/
public boolean getFormat() {
return format;
}
/**
* Sets the tabulation width.
*/
public void setTabulationWidth(int i) {
tabulationWidth = Math.max(i, 0);
}
/**
* Returns whether the tabulation width.
*/
public int getTabulationWidth() {
return tabulationWidth;
}
/**
* Sets the document width.
*/
public void setDocumentWidth(int i) {
documentWidth = Math.max(i, 0);
}
/**
* Returns whether the document width.
*/
public int getDocumentWidth() {
return documentWidth;
}
/**
* Returns the number of newlines in the given char array.
*/
protected int newlines(char[] text) {
int result = 0;
for (int i = 0; i < text.length; i++) {
if (text[i] == 10) {
result++;
}
}
return result;
}
/**
* Prints a single character.
*/
protected void printCharacter(char c) throws IOException {
if (c == 10) {
printNewline();
} else {
column++;
writer.write(c);
}
}
/**
* Prints a newline.
*/
protected void printNewline() throws IOException {
String nl = getNewline();
for (int i = 0; i < nl.length(); i++) {
writer.write(nl.charAt(i));
}
column = 0;
line++;
}
/**
* Prints a string.
*/
protected void printString(String s) throws IOException {
for (int i = 0; i < s.length(); i++) {
printCharacter(s.charAt(i));
}
}
/**
* Prints a char array.
*/
protected void printCharacters(char[] ca) throws IOException {
for (int i = 0; i < ca.length; i++) {
printCharacter(ca[i]);
}
}
/**
* Prints white spaces.
* @param text The space text.
* @param opt whether the space is optional.
*/
protected void printSpaces(char[] text, boolean opt) throws
IOException {
if (getFormat()) {
if (!opt) {
printCharacter(' ');
}
} else {
printCharacters(text);
}
}
/**
* Prints top level white spaces.
* @param text The space text.
* @param opt whether the space is optional.
*/
protected void printTopSpaces(char[] text) throws IOException {
if (getFormat()) {
int nl = newlines(text);
for (int i = 0; i < nl; i++) {
printNewline();
}
} else {
printCharacters(text);
}
}
protected void marginAppend() {
for (int i = 0; i < getTabulationWidth(); i++) {
margin.append(' ');
}
}
protected void marginDelete() {
for (int i = 0; i < getTabulationWidth(); i++) {
margin.deleteCharAt(0);
}
}
/**
* Returns the given content value transformed to replace invalid
* characters with entities.
*/
protected String contentToString(String s) {
StringBuffer result = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '<':
result.append("<");
break;
case '>':
result.append(">");
break;
case '&':
result.append("&");
break;
case '"':
result.append(""");
break;
case '\'':
result.append("'");
break;
default:
result.append(c);
}
}
return result.toString();
}
/** Return the normalizeAttributeValue
* First it pass String param to contentToString(s) then
* It also replace multiple space into single space
* and cariage return/linefeed into single space
*/
protected String normalizeAttributeValue(String s) {
String str = contentToString(s);
StringBuffer sb = new StringBuffer();
/* since batik using jdk1.3 no regex is use, use
StringTokenizer instead */
java.util.StringTokenizer st = new java.util.StringTokenizer
(str);
while (st.hasMoreTokens()) {
sb.append(st.nextToken() + " ");
}
sb.deleteCharAt(sb.length()-1);
return sb.toString();
}
/** write the String into allowable document width and margin.
* The line break is done on word boundary
*/
protected void formatText(String text) throws IOException {
java.util.StringTokenizer st = new java.util.StringTokenizer
(text);
while (st.hasMoreTokens()) {
String str = st.nextToken();
if (str.length() + column > getDocumentWidth()) {
printNewline();
printString(margin.toString());
for(int i=0; i< getTabulationWidth(); i++) {
printCharacter(' ');
}
}
printString(str);
if (st.hasMoreTokens()==true) {
printCharacter(' ');
}
}
}
/**
* Tells whether the given character represents white spaces.
*/
protected boolean isWhiteSpace(char[] text) {
for (int i = 0; i < text.length; i++) {
if (!XMLUtilities.isXMLSpace(text[i])) {
return false;
}
}
return true;
}
/** Return wheter the specified Attr attributeValue is line
breakable on word boundary
[EMAIL PROTECTED] true if line breakable otherwise false
*/
protected boolean isAttributeValueLineBreakable(Attr attr) {
boolean breakable = false;
Element elt = attr.getOwnerElement();
String name = attr.getName();
if (name.equalsIgnoreCase("points")) {
if (elt instanceof SVGPolygonElement || elt instanceof
SVGPolylineElement) {
breakable = true;
}
} else if (name.equalsIgnoreCase("d")) {
if (elt instanceof SVGPathElement) {
breakable = true;
}
} else if (name.equalsIgnoreCase("style")) {
if (elt instanceof SVGStylable) {
breakable = true;
}
}
return breakable;
}
/**
* Prints an SVG document to the given writer.
*/
public void print(Document doc, Writer w) throws
TranscoderException, IOException {
writer = w;
printXMLDecl();
for (Node n = doc.getFirstChild(); n != null; n =
n.getNextSibling()) {
writeNode(n);
}
}
/**
* Prints the XML declaration.
*/
protected void printXMLDecl() throws TranscoderException,
IOException {
if (xmlDeclaration != null) {
printString(xmlDeclaration);
printNewline();
}
}
/**
* Writes a node using the given writer.
*/
protected void writeNode(Node n) throws IOException {
switch (n.getNodeType()) {
case Node.ELEMENT_NODE:
writeElement(n);
break;
case Node.TEXT_NODE:
writeCharacterData(n);
break;
case Node.CDATA_SECTION_NODE:
writeCDATASection(n);
break;
case Node.ENTITY_REFERENCE_NODE:
writeEntityReference(n);
break;
case Node.PROCESSING_INSTRUCTION_NODE:
writePI(n);
break;
case Node.COMMENT_NODE:
writeComment(n);
break;
case Node.DOCUMENT_TYPE_NODE:
break;
default:
throw new Error("Internal error (" + n.getNodeType()
+ ")");
}
}
/** write Element node */
protected void writeElement(Node n) throws IOException {
////////////////////////
// begining of element
if (getFormat()) {
if (canIndent) {
printNewline();
printString(margin.toString());
}
}
int startLine = line;
printCharacter('<');
printString(n.getNodeName());
////////////////////
// attribute stuff
if (n.hasAttributes()) {
NamedNodeMap attr = n.getAttributes();
int len = attr.getLength();
for (int i = 0; i < len; i++) {
Attr a = (Attr)attr.item(i);
// attr name stuff
String attrName = " " + a.getNodeName() + "=";
if (attrName.length() + column > getDocumentWidth()) {
printNewline();
printString(margin.toString());
for(int j=0; j< getTabulationWidth(); j++) {
printCharacter(' ');
}
}
printString(attrName);
// attr value stuff
String attrValue = "\"" + normalizeAttributeValue
(a.getNodeValue()) + "\"";
if (isAttributeValueLineBreakable(a) == true) {
formatText(attrValue);
} else {
printString(attrValue);
}
}
}
////////////////////
// end of element
Node c = n.getFirstChild();
if (c != null) {
printCharacter('>');
level++;
marginAppend();
canIndent = true;
for (; c != null;c = c.getNextSibling()) {
writeNode(c);
}
level--;
marginDelete();
if (getFormat()) {
if (column + n.getNodeName().length() + 3 >=
getDocumentWidth() || startLine != line) {
printNewline();
printString(margin.toString());
}
}
printString("</");
printString(n.getNodeName());
printString(">");
} else {
printString("/>");
}
}
/** write comment node */
protected void writeComment(Node n) throws IOException {
String str = n.getNodeValue();
if (getFormat()) {
if (canIndent) {
printNewline();
printString(margin.toString());
}
printString("<!-- ");
str = contentToString(str);
formatText(str);
if (column + 3 > getDocumentWidth()) {
printNewline();
printString(margin.toString());
}
printString(" -->");
} else {
printString("<!--");
printString(str);
printString("-->");
}
}
/** write CharacterData node */
protected void writeCharacterData(Node n) throws IOException {
String text = contentToString(n.getNodeValue());
if (getFormat()) {
canIndent = true;
char[] data = text.toCharArray();
if (isWhiteSpace(data)) {
int nl = newlines(data);
for (int i = 0; i < nl - 1; i++) {
printNewline();
}
} else {
formatText(text);
}
} else {
printString(text);
}
}
/** write EntityReference node */
protected void writeEntityReference(Node n) throws IOException {
printCharacter('&');
printString(n.getNodeName());
printCharacter(';');
}
/** write CDATASection node */
protected void writeCDATASection(Node n) throws IOException {
printString("<![CDATA[");
printString(n.getNodeValue());
printString("]]>");
}
/** write ProcessingInstruction node */
public void writePI(Node n) throws IOException {
if (getFormat()) {
if (canIndent) {
printNewline();
printString(margin.toString());
}
}
printString("<?");
printString(n.getNodeName());
printString(" ");
printString(n.getNodeValue());
printString("?>");
}
}
Thanks a lot at all svg-developers
Alessandro Peruzzi
--- In [email protected], "Peruzzi Alessandro"
<[EMAIL PROTECTED]> wrote:
>
> Hi.
> Thanks for your reply.
>
> But can you help me with an example of code implemetation?
> I' don't understand how must implements PrettyPrinter with my Dom
> Document of SVG (sorry for my English ) ;-) starting from source
> code I included in my previus message.
>
> Thanks a lot from Alessandro Peruzzi
>
> --- In [email protected], Thomas DeWeese
> <[EMAIL PROTECTED]> wrote:
> > Hi Peruzzi,
> >
> > Peruzzi Alessandro wrote:
> >
> > > When I create an SVG structure for example:
> >
> > > StringWriter strW = new StringWriter();
> > > DOMUtilities.writeDocument(svgDoc, strW);
> > > svgStr = strW.toString();
> > > strW.flush();
> > > strW.close();
> >
> > > now svgStr is a string with svg code.
> > > The ploblem is that this code is in only in one no formated row.
> >
> > This is because DOMUtilities outputs the DOM just as
> > you created it.
> >
> > > ex:
> > > <svg><text x="80" y="120" font-size="8" font-family="times" \
> > > fill="yellow">hello world</text>....</svg>
> > >
> > > In only one row. I'd like this structure:
> > > <svg>
> > > <text ....>hello world</text>
> > >...</svg>
> >
> > You have two options. The first is for you to
> > create text nodes that introduce newlines/indent
> > where you want them. The other option is to use the
> > Batik SVG PrettyPrinting transcoder:
> >
> > org.apache.batik.transcoder.svg2svg.SVGTranscoder
> >
> > > I use normalize() methods but without any result for my scope.
> >
> > Why would you think that normalize would indent your XML?
> >
> > > I hope there is a solution.
> > >
> > > Thanks a lot.
> > > Alessandro Peruzzi
> > >
> > >
> > >
> > >
> > >
> > > -----
> > > To unsubscribe send a message to: svg-developers-
> [EMAIL PROTECTED]
> > > -or-
> > > visit http://groups.yahoo.com/group/svg-developers and
> click "edit my membership"
> > > ----
> > > Yahoo! Groups Links
> > >
> > >
> > >
> > >
> > >
> > >
> > >
-----
To unsubscribe send a message to: [EMAIL PROTECTED]
-or-
visit http://groups.yahoo.com/group/svg-developers and click "edit my
membership"
----
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/svg-developers/
<*> To unsubscribe from this group, send an email to:
[EMAIL PROTECTED]
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/