Skip to content

Commit

Permalink
Ignore child nodes if the instance declaration includes a source
Browse files Browse the repository at this point in the history
  • Loading branch information
lognaturel committed Jul 5, 2019
1 parent d7d7385 commit 684390b
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 7 deletions.
19 changes: 12 additions & 7 deletions src/main/java/org/javarosa/xform/parse/XFormParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -823,13 +823,18 @@ private void parseSubmission(Element submission) {
private void saveInstanceNode(Element instance) {
Element instanceNode = null;
String instanceId = instance.getAttributeValue("", "id");

for (int i = 0; i < instance.getChildCount(); i++) {
if (instance.getType(i) == Node.ELEMENT) {
if (instanceNode != null) {
throw new XFormParseException("XForm Parse: <instance> has more than one child element", instance);
} else {
instanceNode = instance.getElement(i);
String instanceSrc = instance.getAttributeValue("", "src");

// Only consider child nodes if the instance declaration does not include a source.
// TODO: revisit this to allow for a mix of static and dynamic data but beware of https://github.com/opendatakit/javarosa/issues/451
if (instanceSrc == null) {
for (int i = 0; i < instance.getChildCount(); i++) {
if (instance.getType(i) == Node.ELEMENT) {
if (instanceNode != null) {
throw new XFormParseException("XForm Parse: <instance> has more than one child element", instance);
} else {
instanceNode = instance.getElement(i);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ public void externalInstanceDeclaration_ShouldBeIgnored_WhenNotReferenced() thro
evaluationContext.expandReference(treeReference);
}

// See https://github.com/opendatakit/javarosa/issues/451
@Test
public void dummyNodesInExternalInstanceDeclaration_ShouldBeIgnored() throws IOException, XPathSyntaxException {
Path formPath = r("external-select-xml-dummy-nodes.xml");
mapFileToResourcePath(formPath);
FormDef formDef = parse(formPath);

TreeReference treeReference = ((XPathPathExpr) parseXPath("instance('external-xml')/root/item")).getReference();
List<TreeReference> dataSet = formDef.getEvaluationContext().expandReference(treeReference);
assertThat(dataSet.size(), is(12));
}

@Test
public void timesParsingLargeExternalSecondaryInstanceFiles() throws IOException {
Path tempDir = Files.createTempDirectory("javarosa-test-");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms"
xmlns:h="http://www.w3.org/1999/xhtml" >
<h:head>
<h:title>XML External Secondary Instance With Dummy Nodes</h:title>
<model>
<instance>
<data id="external-select-xml">
<first/>
<second/>
<meta>
<instanceID/>
</meta>
</data>
</instance>

<instance id="external-xml" src="jr://file/external-data.xml">
<root>
<item>
<name>_</name>
<label>_</label>
</item>
</root>
</instance>

<bind nodeset="/data/first" type="select1"/>
<bind nodeset="/data/second" type="select1"/>
<bind calculate="concat('uuid:', uuid())" nodeset="/data/meta/instanceID" readonly="true()" type="string"/>
</model>
</h:head>
<h:body>
<select1 ref="/data/first">
<label>First</label>
<itemset nodeset="instance('external-xml')/root/item[first='']">
<value ref="name"/>
<label ref="label"/>
</itemset>
</select1>

<select1 ref="/data/second">
<label>Second</label>
<itemset nodeset="instance('external-xml')/root/item[first=/data/first]">
<value ref="name"/>
<label ref="label"/>
</itemset>
</select1>
</h:body>
</h:html>

0 comments on commit 684390b

Please sign in to comment.