Search in sources :

Example 16 with Element

use of org.kxml2.kdom.Element in project javarosa by opendatakit.

the class XFormParser method parseOsmTags.

/**
 *  Parses the OSM Tag Elements when we are parsing
 *  an OSM Upload element.
 */
private List<OSMTag> parseOsmTags(Element e) {
    List<OSMTag> tags = new ArrayList<>();
    int childCount = e.getChildCount();
    for (int i = 0; i < childCount; ++i) {
        Object child = e.getChild(i);
        if (child instanceof Element) {
            Element childEl = (Element) child;
            String name = childEl.getName();
            // the child elements we are interested in are tags
            if (name.equals("tag")) {
                OSMTag tag = new OSMTag();
                tags.add(tag);
                // parse tag key
                int attrCount = childEl.getAttributeCount();
                for (int j = 0; j < attrCount; ++j) {
                    String attrName = childEl.getAttributeName(j);
                    if (attrName.equals("key")) {
                        tag.key = childEl.getAttributeValue(j);
                        // parse tag children
                        int tagChildCount = childEl.getChildCount();
                        for (int k = 0; k < tagChildCount; ++k) {
                            Object child2 = childEl.getChild(k);
                            if (child2 instanceof Element) {
                                Element tagChildEl = (Element) child2;
                                String tagChildName = tagChildEl.getName();
                                // a tag child might be a label
                                if (tagChildName.equals("label")) {
                                    tag.label = tagChildEl.getText(0);
                                } else // a tag child might be an item
                                if (tagChildName.equals("item")) {
                                    OSMTagItem item = new OSMTagItem();
                                    tag.items.add(item);
                                    // parse item children
                                    int itemChildCount = tagChildEl.getChildCount();
                                    for (int l = 0; l < itemChildCount; ++l) {
                                        Object child3 = tagChildEl.getChild(l);
                                        if (child3 instanceof Element) {
                                            Element itemChildEl = (Element) child3;
                                            String itemChildName = itemChildEl.getName();
                                            // an item child might be a label
                                            if (itemChildName.equals("label")) {
                                                item.label = itemChildEl.getText(0);
                                            } else // an item child might be a value
                                            if (itemChildName.equals("value")) {
                                                item.value = itemChildEl.getText(0);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return tags;
}
Also used : OSMTagItem(org.javarosa.core.model.osm.OSMTagItem) OSMTag(org.javarosa.core.model.osm.OSMTag) TreeElement(org.javarosa.core.model.instance.TreeElement) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) Element(org.kxml2.kdom.Element) IFormElement(org.javarosa.core.model.IFormElement) ArrayList(java.util.ArrayList)

Example 17 with Element

use of org.kxml2.kdom.Element in project javarosa by opendatakit.

the class XFormParser method loadInstanceData.

// TODO: hook here for turning sub-trees into complex IAnswerData objects (like for immunizations)
// FIXME: the 'ref' and FormDef parameters (along with the helper function above that initializes them) are only needed so that we
// can fetch QuestionDefs bound to the given node, as the QuestionDef reference is needed to properly represent answers
// to select questions. obviously, we want to fix this.
private static void loadInstanceData(Element node, TreeElement cur, FormDef f) {
    int numChildren = node.getChildCount();
    boolean hasElements = false;
    for (int i = 0; i < numChildren; i++) {
        if (node.getType(i) == Node.ELEMENT) {
            hasElements = true;
            break;
        }
    }
    if (hasElements) {
        // stores max multiplicity seen for a given node name thus far
        HashMap<String, Integer> multiplicities = new HashMap<>();
        for (int i = 0; i < numChildren; i++) {
            if (node.getType(i) == Node.ELEMENT) {
                Element child = node.getElement(i);
                String name = child.getName();
                int index;
                boolean isTemplate = isTemplate(child);
                if (isTemplate) {
                    index = TreeReference.INDEX_TEMPLATE;
                } else {
                    // update multiplicity counter
                    Integer mult = multiplicities.get(name);
                    index = (mult == null ? 0 : mult + 1);
                    multiplicities.put(name, index);
                }
                loadInstanceData(child, cur.getChild(name, index), f);
            }
        }
    } else {
        String text = getXMLText(node, true);
        if (text != null && text.trim().length() > 0) {
            // ignore text that is only whitespace
            // TODO: custom data types? modelPrototypes?
            cur.setValue(XFormAnswerDataParser.getAnswerData(text, cur.getDataType(), ghettoGetQuestionDef(cur.getDataType(), f, cur.getRef())));
        }
    }
}
Also used : HashMap(java.util.HashMap) TreeElement(org.javarosa.core.model.instance.TreeElement) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) Element(org.kxml2.kdom.Element) IFormElement(org.javarosa.core.model.IFormElement)

Example 18 with Element

use of org.kxml2.kdom.Element in project javarosa by opendatakit.

the class XFormParser method parseControl.

/**
 * Parses a form control element into a {@link org.javarosa.core.model.QuestionDef} and attaches it to its parent.
 *
 * @param parent                the form control element's parent
 * @param e                     the form control element to parse
 * @param controlType           one of the control types defined in {@link org.javarosa.core.model.Constants}
 * @param additionalUsedAtts    attributes specific to the control type
 * @param passedThroughAtts     attributes specific to the control type that should be passed through to
 *                              additionalAttributes for historical reasons
 * @return                      a {@link org.javarosa.core.model.QuestionDef} representing the form control element
 */
private QuestionDef parseControl(IFormElement parent, Element e, int controlType, List<String> additionalUsedAtts, List<String> passedThroughAtts) {
    final QuestionDef question = questionForControlType(controlType);
    // until we come up with a better scheme
    question.setID(serialQuestionID++);
    final List<String> usedAtts = new ArrayList<>(Arrays.asList(REF_ATTR, BIND_ATTR, APPEARANCE_ATTR));
    if (additionalUsedAtts != null) {
        usedAtts.addAll(additionalUsedAtts);
    }
    IDataReference dataRef = null;
    boolean refFromBind = false;
    String ref = e.getAttributeValue(null, REF_ATTR);
    String bind = e.getAttributeValue(null, BIND_ATTR);
    if (bind != null) {
        DataBinding binding = bindingsByID.get(bind);
        if (binding == null) {
            throw new XFormParseException("XForm Parse: invalid binding ID '" + bind + "'", e);
        }
        dataRef = binding.getReference();
        refFromBind = true;
    } else if (ref != null) {
        try {
            dataRef = new XPathReference(ref);
        } catch (RuntimeException el) {
            Std.out.println(XFormParser.getVagueLocation(e));
            throw el;
        }
    } else {
        // noinspection StatementWithEmptyBody
        if (controlType == Constants.CONTROL_TRIGGER) {
        // TODO: special handling for triggers? also, not all triggers created equal
        } else {
            throw new XFormParseException("XForm Parse: input control with neither 'ref' nor 'bind'", e);
        }
    }
    if (dataRef != null) {
        if (!refFromBind) {
            dataRef = getAbsRef(dataRef, parent);
        }
        question.setBind(dataRef);
        if (controlType == Constants.CONTROL_SELECT_ONE) {
            selectOnes.add((TreeReference) dataRef.getReference());
        } else if (controlType == Constants.CONTROL_SELECT_MULTI) {
            selectMultis.add((TreeReference) dataRef.getReference());
        }
    }
    boolean isSelect = (controlType == Constants.CONTROL_SELECT_MULTI || controlType == Constants.CONTROL_SELECT_ONE);
    question.setControlType(controlType);
    question.setAppearanceAttr(e.getAttributeValue(null, APPEARANCE_ATTR));
    for (int i = 0; i < e.getChildCount(); i++) {
        int type = e.getType(i);
        Element child = (type == Node.ELEMENT ? e.getElement(i) : null);
        String childName = (child != null ? child.getName() : null);
        if (LABEL_ELEMENT.equals(childName)) {
            parseQuestionLabel(question, child);
        } else if ("hint".equals(childName)) {
            parseHint(question, child);
        } else if (isSelect && "item".equals(childName)) {
            parseItem(question, child);
        } else if (isSelect && "itemset".equals(childName)) {
            parseItemset(question, child, parent);
        }
    }
    if (isSelect) {
        if (question.getNumChoices() > 0 && question.getDynamicChoices() != null) {
            throw new XFormParseException("Select question contains both literal choices and <itemset>");
        } else if (question.getNumChoices() == 0 && question.getDynamicChoices() == null) {
            throw new XFormParseException("Select question has no choices");
        }
    }
    if (question instanceof RangeQuestion) {
        populateQuestionWithRangeAttributes((RangeQuestion) question, e);
    }
    parent.addChild(question);
    processAdditionalAttributes(question, e, usedAtts, passedThroughAtts);
    return question;
}
Also used : IDataReference(org.javarosa.core.model.IDataReference) TreeElement(org.javarosa.core.model.instance.TreeElement) AbstractTreeElement(org.javarosa.core.model.instance.AbstractTreeElement) Element(org.kxml2.kdom.Element) IFormElement(org.javarosa.core.model.IFormElement) ArrayList(java.util.ArrayList) XPathReference(org.javarosa.model.xform.XPathReference) TreeReference(org.javarosa.core.model.instance.TreeReference) RangeQuestion(org.javarosa.core.model.RangeQuestion) DataBinding(org.javarosa.core.model.DataBinding) QuestionDef(org.javarosa.core.model.QuestionDef)

Example 19 with Element

use of org.kxml2.kdom.Element in project javarosa by opendatakit.

the class XFormSerializer method elementToString.

public static String elementToString(Element e) {
    KXmlSerializer serializer = new KXmlSerializer();
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(bos);
    String s = null;
    try {
        serializer.setOutput(dos, null);
        e.write(serializer);
        serializer.flush();
        s = new String(bos.toByteArray(), "UTF-8");
        return s;
    } catch (UnsupportedEncodingException uce) {
        Std.printStack(uce);
    } catch (Exception ex) {
        Std.printStack(ex);
        return null;
    }
    return null;
}
Also used : DataOutputStream(java.io.DataOutputStream) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) KXmlSerializer(org.kxml2.io.KXmlSerializer) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 20 with Element

use of org.kxml2.kdom.Element in project javarosa by opendatakit.

the class XFormSerializingVisitor method serializeNode.

public Element serializeNode(TreeElement instanceNode) {
    // don't set anything on this element yet, as it might get overwritten
    Element e = new Element();
    // don't serialize template nodes or non-relevant nodes
    if ((respectRelevance && !instanceNode.isRelevant()) || instanceNode.getMult() == TreeReference.INDEX_TEMPLATE) {
        return null;
    }
    if (instanceNode.getValue() != null) {
        Object serializedAnswer;
        try {
            serializedAnswer = serializer.serializeAnswerData(instanceNode.getValue(), instanceNode.getDataType());
        } catch (RuntimeException ex) {
            throw new RuntimeException("Unable to serialize " + instanceNode.getValue().toString() + ". Exception: " + ex.toString());
        }
        if (serializedAnswer instanceof Element) {
            e = (Element) serializedAnswer;
        } else if (serializedAnswer instanceof String) {
            e = new Element();
            e.addChild(Node.TEXT, (String) serializedAnswer);
        } else {
            throw new RuntimeException("Can't handle serialized output for" + instanceNode.getValue().toString() + ", " + serializedAnswer);
        }
        if (serializer.containsExternalData(instanceNode.getValue()).booleanValue()) {
            IDataPointer[] pointer = serializer.retrieveExternalDataPointer(instanceNode.getValue());
            for (int i = 0; i < pointer.length; ++i) {
                dataPointers.add(pointer[i]);
            }
        }
    } else {
        // make sure all children of the same tag name are written en bloc
        List<String> childNames = new ArrayList<String>(instanceNode.getNumChildren());
        for (int i = 0; i < instanceNode.getNumChildren(); i++) {
            String childName = instanceNode.getChildAt(i).getName();
            if (!childNames.contains(childName))
                childNames.add(childName);
        }
        for (int i = 0; i < childNames.size(); i++) {
            String childName = (String) childNames.get(i);
            int mult = instanceNode.getChildMultiplicity(childName);
            for (int j = 0; j < mult; j++) {
                Element child = serializeNode(instanceNode.getChild(childName, j));
                if (child != null) {
                    e.addChild(Node.ELEMENT, child);
                }
            }
        }
    }
    e.setName(instanceNode.getName());
    // add hard-coded attributes
    for (int i = 0; i < instanceNode.getAttributeCount(); i++) {
        String namespace = instanceNode.getAttributeNamespace(i);
        String name = instanceNode.getAttributeName(i);
        String val = instanceNode.getAttributeValue(i);
        // is it legal for getAttributeValue() to return null? playing it safe for now and assuming yes
        if (val == null) {
            val = "";
        }
        e.setAttribute(namespace, name, val);
    }
    if (instanceNode.getNamespace() != null) {
        e.setNamespace(instanceNode.getNamespace());
    }
    return e;
}
Also used : TreeElement(org.javarosa.core.model.instance.TreeElement) Element(org.kxml2.kdom.Element) ArrayList(java.util.ArrayList) IDataPointer(org.javarosa.core.data.IDataPointer)

Aggregations

Element (org.kxml2.kdom.Element)50 TreeElement (org.javarosa.core.model.instance.TreeElement)25 AbstractTreeElement (org.javarosa.core.model.instance.AbstractTreeElement)23 ArrayList (java.util.ArrayList)21 IOException (java.io.IOException)17 IFormElement (org.javarosa.core.model.IFormElement)17 KXmlParser (org.kxml2.io.KXmlParser)12 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)12 File (java.io.File)8 Test (org.junit.Test)7 ParsingException (org.opendatakit.briefcase.model.ParsingException)7 XmlPullParser (org.xmlpull.v1.XmlPullParser)7 Document (org.kxml2.kdom.Document)6 UnsupportedEncodingException (java.io.UnsupportedEncodingException)4 FileInputStream (java.io.FileInputStream)3 FileNotFoundException (java.io.FileNotFoundException)3 OutputStreamWriter (java.io.OutputStreamWriter)3 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)3 HashMap (java.util.HashMap)3 KXmlSerializer (org.kxml2.io.KXmlSerializer)3