Skip to content

Commit cfa9e52

Browse files
committed
doing battle with XML and format()
1 parent c3c2248 commit cfa9e52

File tree

4 files changed

+103
-33
lines changed

4 files changed

+103
-33
lines changed

android/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() {

core/src/processing/data/XML.java

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -770,19 +770,25 @@ public void setContent(String text) {
770770
public String format(int indent) {
771771
try {
772772
// entities = doctype.getEntities()
773+
boolean useIndentAmount = false;
773774
TransformerFactory factory = TransformerFactory.newInstance();
774775
if (indent != -1) {
775-
factory.setAttribute("indent-number", indent);
776+
try {
777+
factory.setAttribute("indent-number", indent);
778+
} catch (IllegalArgumentException e) {
779+
useIndentAmount = true;
780+
}
776781
}
777782
Transformer transformer = factory.newTransformer();
778783

779784
// Add the XML declaration at the top if this node is the root and we're
780785
// not writing to a single line (indent = -1 means single line).
781-
if (indent == -1 || parent != null) {
786+
if (indent == -1 || parent == null) {
782787
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
783788
} else {
784789
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
785790
}
791+
786792
// transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "sample.dtd");
787793

788794
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
@@ -794,17 +800,20 @@ public String format(int indent) {
794800
// transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
795801
// "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
796802

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+
797808
// transformer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1");
798809
// transformer.setOutputProperty(OutputKeys.ENCODING,"UTF8");
799810
transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
800811
// transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS
801-
// indent by default, but sometimes this needs to be turned off
802-
if (indent != 0) {
803-
//transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent));
804-
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
805-
} else {
806-
transformer.setOutputProperty(OutputKeys.INDENT, "no");
807-
}
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+
808817
// Properties p = transformer.getOutputProperties();
809818
// for (Object key : p.keySet()) {
810819
// System.out.println(key + " -> " + p.get(key));
@@ -819,25 +828,45 @@ public String format(int indent) {
819828
// please contribute. I've wasted too much of my Sunday on it. But at
820829
// least the Giants are getting blown out by the Falcons.
821830

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+
822836
StringWriter tempWriter = new StringWriter();
823837
StreamResult tempResult = new StreamResult(tempWriter);
824838
transformer.transform(new DOMSource(node), tempResult);
825839
String[] tempLines = PApplet.split(tempWriter.toString(), '\n');
826-
if (tempLines[0].startsWith("<?xml")) {
840+
PApplet.println(tempLines);
841+
if (tempLines[0].startsWith(decl)) {
827842
// Remove XML declaration from the top before slamming into one line
828-
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+
}
829855
}
830856
String singleLine = PApplet.join(PApplet.trim(tempLines), "");
831857
if (indent == -1) {
832858
return singleLine;
833859
}
834860

861+
// Since the indent is not -1, bring back the XML declaration
862+
//transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
863+
835864
StringWriter stringWriter = new StringWriter();
836865
StreamResult xmlOutput = new StreamResult(stringWriter);
837866
// DOMSource source = new DOMSource(node);
838867
Source source = new StreamSource(new StringReader(singleLine));
839868
transformer.transform(source, xmlOutput);
840-
return stringWriter.toString();
869+
return decl + "\n" + stringWriter.toString();
841870
// return xmlOutput.getWriter().toString();
842871

843872
} catch (Exception e) {

core/todo.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ o also shorter than getCount() or getLength()
107107
o why not HashMap and ArrayList for JSON?
108108
o could enable loadHash() and loadArray() functions
109109
X because the types coming back out would always have to be cast
110-
_ add loadDict() and loadList() for JSON?
111-
_ Dict and List could be interfaces?
110+
o add loadDict() and loadList() for JSON?
111+
o Dict and List could be interfaces?
112112
_ JSONObject.has(key) vs XML.hasAttribute(attr) vs HashMap.containsKey()
113113
_ and how it should be handled with hash/dict
114114
_ right now using hasKey().. in JSONObject

todo.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ X remove separate launch of QT movie creator
4444

4545
manindra
4646
M bug that was causing the Debugger to point to wrong break point line numbers
47+
M 'Debug' button does not re-run the project when it is already running.
48+
M http://code.google.com/p/processing/issues/detail?id=1504
4749

4850
earlier
4951
X include debug mode as 'experimental'?
@@ -61,11 +63,12 @@ X removed in 2.0b7, because it has bugs and is no longer compatible
6163
o also can have case of opening two of same sketch at once
6264
o if sketch was open, then restart by dragging the .pde to p5.app
6365

64-
_ crashes when selecting "Show Sketch Folder" with Windows 7
65-
_ http://code.google.com/p/processing/issues/detail?id=1473
66-
6766
https://processing-js.lighthouseapp.com/
6867

68+
_ add Iterator as an import?
69+
_ for others like collections and Date, show warning and option to add?
70+
_ along with warning that it's not supported
71+
6972
_ remove sketch.properties when moving back to the default?
7073
_ or can we not do this, because the next mode needs this?
7174

@@ -862,6 +865,9 @@ _ avoid some confusion for when describing the libraries folder to users
862865

863866
DIST / Windows
864867

868+
_ crash when selecting "Show Sketch Folder" with Windows 7
869+
_ might be a java.awt.Desktop problem
870+
_ http://code.google.com/p/processing/issues/detail?id=1473
865871
_ does launching p5 from inside the .zip folder cause it to quit immediately?
866872
_ fix line endings in revisions.txt for windows
867873
_ exe instead of bat to make exported apps run in 64-bit

0 commit comments

Comments
 (0)