Skip to content

Commit e9c0d47

Browse files
committed
doing battle with XML and format()
1 parent 06d2815 commit e9c0d47

1 file changed

Lines changed: 51 additions & 16 deletions

File tree

core/src/processing/data/XML.java

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,13 @@ protected XML(XML parent, Node node) {
157157

158158

159159
/**
160-
* xxxxxxx
161-
*
162160
* @webref xml:method
163161
* @brief Converts String content to an XML object
164162
* @param data the content to be parsed as XML
165163
* @return an XML object, or null
166164
* @throws SAXException
167165
* @throws ParserConfigurationException
168166
* @throws IOException
169-
* @see PApplet#loadXML(String)
170167
*/
171168
static public XML parse(String data) throws IOException, ParserConfigurationException, SAXException {
172169
return XML.parse(data, null);
@@ -724,7 +721,6 @@ public double getDouble(String name) {
724721
*
725722
* @param name the non-null full name of the attribute.
726723
* @param defaultValue the default value of the attribute.
727-
*
728724
* @return the value, or defaultValue if the attribute does not exist.
729725
*/
730726
public double getDouble(String name, double defaultValue) {
@@ -764,24 +760,35 @@ public void setContent(String text) {
764760

765761
/**
766762
* Format this XML data as a String.
763+
*
764+
* @webref xml:method
765+
* @brief Formats XML data as a String
767766
* @param indent -1 for a single line (and no declaration), >= 0 for indents and newlines
767+
* @return the content
768+
* @see XML#toString()
768769
*/
769770
public String format(int indent) {
770771
try {
771772
// entities = doctype.getEntities()
773+
boolean useIndentAmount = false;
772774
TransformerFactory factory = TransformerFactory.newInstance();
773775
if (indent != -1) {
774-
factory.setAttribute("indent-number", indent);
776+
try {
777+
factory.setAttribute("indent-number", indent);
778+
} catch (IllegalArgumentException e) {
779+
useIndentAmount = true;
780+
}
775781
}
776782
Transformer transformer = factory.newTransformer();
777783

778784
// Add the XML declaration at the top if this node is the root and we're
779785
// not writing to a single line (indent = -1 means single line).
780-
if (indent == -1 || parent != null) {
786+
if (indent == -1 || parent == null) {
781787
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
782788
} else {
783789
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
784790
}
791+
785792
// transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "sample.dtd");
786793

787794
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
@@ -793,17 +800,20 @@ public String format(int indent) {
793800
// transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
794801
// "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
795802

803+
// For Android, because (at least 2.3.3) doesn't like indent-number
804+
if (useIndentAmount) {
805+
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent));
806+
}
807+
796808
// transformer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1");
797809
// transformer.setOutputProperty(OutputKeys.ENCODING,"UTF8");
798810
transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
799811
// transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS
800-
// indent by default, but sometimes this needs to be turned off
801-
if (indent != 0) {
802-
//transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent));
803-
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
804-
} else {
805-
transformer.setOutputProperty(OutputKeys.INDENT, "no");
806-
}
812+
813+
// Always indent, otherwise the XML declaration will just be jammed
814+
// onto the first line with the XML code as well.
815+
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
816+
807817
// Properties p = transformer.getOutputProperties();
808818
// for (Object key : p.keySet()) {
809819
// System.out.println(key + " -> " + p.get(key));
@@ -818,25 +828,45 @@ public String format(int indent) {
818828
// please contribute. I've wasted too much of my Sunday on it. But at
819829
// least the Giants are getting blown out by the Falcons.
820830

831+
final String decl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
832+
833+
// needed for splitting or when adding decl below?
834+
//System.getProperty("line.separator")
835+
821836
StringWriter tempWriter = new StringWriter();
822837
StreamResult tempResult = new StreamResult(tempWriter);
823838
transformer.transform(new DOMSource(node), tempResult);
824839
String[] tempLines = PApplet.split(tempWriter.toString(), '\n');
825-
if (tempLines[0].startsWith("<?xml")) {
840+
PApplet.println(tempLines);
841+
if (tempLines[0].startsWith(decl)) {
826842
// Remove XML declaration from the top before slamming into one line
827-
tempLines = PApplet.subset(tempLines, 1);
843+
int declEnd = tempLines[0].indexOf("?>") + 2;
844+
//if (tempLines[0].length() == decl.length()) {
845+
if (tempLines[0].length() == declEnd) {
846+
// If it's all the XML declaration, remove it
847+
PApplet.println("removing first line");
848+
tempLines = PApplet.subset(tempLines, 1);
849+
} else {
850+
PApplet.println("removing part of first line");
851+
// If the first node has been moved to this line, be more careful
852+
//tempLines[0] = tempLines[0].substring(decl.length());
853+
tempLines[0] = tempLines[0].substring(declEnd);
854+
}
828855
}
829856
String singleLine = PApplet.join(PApplet.trim(tempLines), "");
830857
if (indent == -1) {
831858
return singleLine;
832859
}
833860

861+
// Since the indent is not -1, bring back the XML declaration
862+
//transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
863+
834864
StringWriter stringWriter = new StringWriter();
835865
StreamResult xmlOutput = new StreamResult(stringWriter);
836866
// DOMSource source = new DOMSource(node);
837867
Source source = new StreamSource(new StringReader(singleLine));
838868
transformer.transform(source, xmlOutput);
839-
return stringWriter.toString();
869+
return decl + "\n" + stringWriter.toString();
840870
// return xmlOutput.getWriter().toString();
841871

842872
} catch (Exception e) {
@@ -850,6 +880,11 @@ public String format(int indent) {
850880
* Return the XML document formatted with two spaces for indents.
851881
* Chosen to do this since it's the most common case (e.g. with println()).
852882
* Same as format(2). Use the format() function for more options.
883+
*
884+
* @webref xml:method
885+
* @brief Gets XML data as a String using default formatting
886+
* @return the content
887+
* @see XML#format(int)
853888
*/
854889
@Override
855890
public String toString() {

0 commit comments

Comments
 (0)