Skip to content

Commit 7c748ca

Browse files
committed
fix Model.fromXml() failure is model has no attribute value; use stax to parse xml instead of dom
1 parent bb50857 commit 7c748ca

File tree

3 files changed

+52
-27
lines changed

3 files changed

+52
-27
lines changed

activejdbc/src/main/java/org/javalite/activejdbc/Model.java

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@
3030
import org.javalite.common.Escape;
3131
import org.slf4j.Logger;
3232
import org.slf4j.LoggerFactory;
33-
import org.w3c.dom.Document;
34-
import org.w3c.dom.Element;
35-
import org.w3c.dom.Node;
36-
import org.w3c.dom.NodeList;
37-
38-
import javax.xml.parsers.DocumentBuilderFactory;
33+
import javax.xml.stream.XMLInputFactory;
34+
import javax.xml.stream.XMLStreamConstants;
35+
import javax.xml.stream.XMLStreamException;
36+
import javax.xml.stream.XMLStreamReader;
3937
import java.io.*;
4038
import java.math.BigDecimal;
4139
import java.sql.Clob;
@@ -45,6 +43,7 @@
4543
import java.util.*;
4644

4745
import static org.javalite.common.Inflector.*;
46+
import static org.javalite.common.Util.blank;
4847
import static org.javalite.common.Util.empty;
4948
import static org.javalite.common.Util.join;
5049

@@ -798,29 +797,31 @@ public String toString() {
798797
* @param xml xml to read model attributes from.
799798
*/
800799
public void fromXml(String xml) {
801-
802-
try{
803-
//such dumb API!
804-
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes()));
805-
String topTag = underscore(getClass().getSimpleName());
806-
Element root = document.getDocumentElement();
807-
808-
if(!root.getTagName().equals(topTag)){
809-
throw new InitException("top node has to match model name: " + topTag);
810-
}
811-
NodeList childNodes = root.getChildNodes();
812-
813-
Map<String, String> attributesMap = new HashMap<String, String>();
814-
for(int i = 0; i < childNodes.getLength();i++){
815-
Node node = childNodes.item(i);
816-
if(node instanceof Element){
817-
Element child = (Element) node;
818-
attributesMap.put(child.getTagName(), child.getFirstChild().getNodeValue());//this is even dumber!
800+
try {
801+
XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new ByteArrayInputStream(xml.getBytes()));
802+
String attr = null;
803+
String chars = null;
804+
Map<Object, Object> res = new HashMap<Object, Object>();
805+
while (reader.hasNext()) {
806+
int event = reader.next();
807+
switch (event) {
808+
case XMLStreamConstants.START_ELEMENT:
809+
attr = reader.getLocalName();
810+
break;
811+
case XMLStreamConstants.CHARACTERS:
812+
chars = reader.getText().trim();;
813+
break;
814+
case XMLStreamConstants.END_ELEMENT:
815+
if (attr != null && !blank(chars)) {
816+
res.put(attr, chars);
817+
}
818+
attr = chars = null;
819+
break;
819820
}
820821
}
821-
fromMap(attributesMap);
822-
}catch(Exception e){
823-
throw new InitException(e);
822+
fromMap(res);
823+
} catch (XMLStreamException e) {
824+
throw new InitException(e);
824825
}
825826
}
826827

activejdbc/src/test/java/org/javalite/activejdbc/ToFromXmlSpec.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,23 @@ public void shouldParseAttributesFromXml() throws ParseException {
6666
a(p.getDate("dob")).shouldBeEqual(f.parse("1962-06-13"));
6767
}
6868

69+
@Test
70+
public void shouldNotFailXmlNoValue() throws ParseException {
71+
deleteAndPopulateTables("people");
72+
73+
Person p = new Person();
74+
String xml = readResource("/person_no_val.xml");
75+
p.fromXml(xml);
76+
p.saveIt();
77+
p.refresh();
78+
79+
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
80+
81+
a(p.get("name")).shouldBeEqual("John");
82+
a(p.get("last_name")).shouldBeEqual("Doe");
83+
a(p.getDate("graduation_date")).shouldBeNull();
84+
a(p.getDate("dob")).shouldBeEqual(f.parse("1962-06-13"));
85+
}
6986

7087
@Test
7188
public void shouldIncludeChildren(){
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<person>
3+
<graduation_date/>
4+
<dob>1962-06-13</dob>
5+
<name>John</name>
6+
<last_name>Doe</last_name>
7+
</person>

0 commit comments

Comments
 (0)