List of usage examples for org.dom4j Node ATTRIBUTE_NODE
short ATTRIBUTE_NODE
To view the source code for org.dom4j Node ATTRIBUTE_NODE.
Click Source Link
From source file:org.jasig.portal.io.xml.SpELDataTemplatingStrategy.java
License:Apache License
@Override public Source processTemplates(Document data, String filename) { log.trace("Processing templates for document XML={}", data.asXML()); for (String xpath : XPATH_EXPRESSIONS) { @SuppressWarnings("unchecked") List<Node> nodes = data.selectNodes(xpath); for (Node n : nodes) { String inpt, otpt;/* ww w. ja v a2 s. c o m*/ switch (n.getNodeType()) { case org.w3c.dom.Node.ATTRIBUTE_NODE: Attribute a = (Attribute) n; inpt = a.getValue(); otpt = processText(inpt); if (otpt == null) { throw new RuntimeException("Invalid expression '" + inpt + "' in file " + filename); } if (!otpt.equals(inpt)) { a.setValue(otpt); } break; case org.w3c.dom.Node.TEXT_NODE: case org.w3c.dom.Node.CDATA_SECTION_NODE: inpt = n.getText(); otpt = processText(inpt); if (otpt == null) { throw new RuntimeException("Invalid expression '" + inpt + "' in file " + filename); } if (!otpt.equals(inpt)) { n.setText(otpt); } break; default: String msg = "Unsupported node type: " + n.getNodeTypeName(); throw new RuntimeException(msg); } } } final SAXSource rslt = new DocumentSource(data); rslt.setSystemId(filename); // must be set, else import chokes return rslt; }
From source file:org.jasig.portal.tenants.TemplateDataTenantOperationsListener.java
License:Apache License
@Override public void onCreate(final ITenant tenant) { final StandardEvaluationContext ctx = new StandardEvaluationContext(); ctx.setRootObject(new RootObjectImpl(tenant)); /*/*ww w .j a v a 2 s .c o m*/ * First load dom4j Documents and sort the entity files into the proper order */ final Map<PortalDataKey, Set<Document>> importQueue = new HashMap<PortalDataKey, Set<Document>>(); Resource rsc = null; try { for (Resource r : templateResources) { rsc = r; if (log.isDebugEnabled()) { log.debug("Loading template resource file for tenant " + "'" + tenant.getFname() + "': " + rsc.getFilename()); } final Document doc = reader.read(rsc.getInputStream()); final QName qname = doc.getRootElement().getQName(); PortalDataKey atLeastOneMatchingDataKey = null; for (PortalDataKey pdk : dataKeyImportOrder) { // Matching is tougher because it's dom4j <> w3c... boolean matches = qname.getName().equals(pdk.getName().getLocalPart()) && qname.getNamespaceURI().equals(pdk.getName().getNamespaceURI()); if (matches) { // Found the right bucket... atLeastOneMatchingDataKey = pdk; Set<Document> bucket = importQueue.get(atLeastOneMatchingDataKey); if (bucket == null) { // First of these we've seen; create the bucket; bucket = new HashSet<Document>(); importQueue.put(atLeastOneMatchingDataKey, bucket); } bucket.add(doc); /* * At this point, we would normally add a break; * statement, but group_membership.xml files need to * match more than one PortalDataKey. */ } } if (atLeastOneMatchingDataKey == null) { // We can't proceed throw new RuntimeException( "No PortalDataKey found for QName: " + doc.getRootElement().getQName()); } } } catch (Exception e) { throw new RuntimeException( "Failed to process the specified template: " + (rsc != null ? rsc.getFilename() : ""), e); } log.trace("Ready to import data entity templates for new tenant '{}'; importQueue={}", tenant.getName(), importQueue); /* * Now import the identified entities each bucket in turn */ Document doc = null; org.w3c.dom.Document w3c = null; try { for (PortalDataKey pdk : dataKeyImportOrder) { Set<Document> bucket = importQueue.get(pdk); if (bucket != null) { log.debug("Importing the specified PortalDataKey tenant '{}': {}", tenant.getName(), pdk.getName()); for (Document d : bucket) { doc = d; log.trace("Importing document XML={}", doc.asXML()); for (String xpath : XPATH_EXPRESSIONS) { @SuppressWarnings("unchecked") List<Node> nodes = doc.selectNodes(xpath); for (Node n : nodes) { String inpt, otpt; switch (n.getNodeType()) { case org.w3c.dom.Node.ATTRIBUTE_NODE: Attribute a = (Attribute) n; inpt = a.getValue(); otpt = processText(inpt, ctx); if (!otpt.equals(inpt)) { a.setValue(otpt); } break; case org.w3c.dom.Node.TEXT_NODE: Text t = (Text) n; inpt = t.getText(); otpt = processText(inpt, ctx); if (!otpt.equals(inpt)) { t.setText(otpt); } break; default: String msg = "Unsupported node type: " + n.getNodeTypeName(); throw new RuntimeException(msg); } } } w3c = writer.write(doc, domImpl); Source source = new DOMSource(w3c); source.setSystemId(rsc.getFilename()); // must be set, else import chokes dataHandlerService.importData(source, pdk); } } } } catch (Exception e) { log.warn("w3c DOM=" + this.nodeToString(w3c)); throw new RuntimeException( "Failed to process the specified template document: " + (doc != null ? doc.asXML() : ""), e); } }
From source file:org.openadaptor.auxil.convertor.map.Dom4JDocumentMapFacade.java
License:Open Source License
/** * Extract value from a single node/*from ww w. j a v a2s.c o m*/ * <br> * <UL> * <LI>If an Element return the element reference. * <LI>If an Attribute return the attribute value * <LI>If text (or CDATA) return it. * <LI>If null return null. * @param node Node from which to extract a value * @return Reference to Element, or String representation of value. */ private Object getSingleValuedResult(Node node) { Object result = null; switch (node.getNodeType()) { case Node.ELEMENT_NODE: result = (Element) node; break; case Node.ATTRIBUTE_NODE: result = ((Attribute) node).getValue(); break; case Node.TEXT_NODE: case Node.CDATA_SECTION_NODE: //Not sure about this one! result = node.getText(); break; } return result; }
From source file:org.orbeon.oxf.processor.pipeline.ast.ASTNodeContainer.java
License:Open Source License
/** * Use specified location if there is one. Otherwise if a node has been provided use the * location of the node. If no node and no location then return hull. *//*from w ww. j a v a2s .c o m*/ public LocationData getLocationData() { final LocationData ret; if (locationData != null) { ret = locationData; } else if (node == null) { ret = null; } else if (node.getNodeType() == org.dom4j.Node.ELEMENT_NODE) { ret = (LocationData) ((org.dom4j.Element) node).getData(); } else if (node.getNodeType() == org.dom4j.Node.ATTRIBUTE_NODE) { ret = (LocationData) ((org.dom4j.Attribute) node).getData(); } else { ret = null; } return ret; }
From source file:org.orbeon.oxf.xforms.action.actions.XFormsInsertAction.java
License:Open Source License
public static List<NodeInfo> doInsert(XFormsContainingDocument containingDocument, IndentedLogger indentedLogger, String positionAttribute, List collectionToBeUpdated, NodeInfo insertContextNodeInfo, List<Item> originItems, int insertionIndex, boolean doClone, boolean doDispatch) { final boolean isEmptyNodesetBinding = collectionToBeUpdated == null || collectionToBeUpdated.size() == 0; // "3. The origin node-set is determined." // "5. Each node in the origin node-set is cloned in the order it appears in the origin node-set." final List<Node> sourceNodes; final List<Node> clonedNodes; {/*from ww w . j a v a 2 s. c om*/ final List<Node> clonedNodesTemp; if (originItems == null) { // There are no explicitly specified origin objects, use node from Node Set Binding node-set // "If the origin attribute is not given and the Node Set Binding node-set is empty, then the origin // node-set is the empty node-set. [...] The insert action is terminated with no effect if the // origin node-set is the empty node-set." if (isEmptyNodesetBinding) { if (indentedLogger != null && indentedLogger.isDebugEnabled()) indentedLogger.logDebug("xf:insert", "origin node-set from node-set binding is empty, terminating"); return Collections.EMPTY_LIST; } // "Otherwise, if the origin attribute is not given, then the origin node-set consists of the last // node of the Node Set Binding node-set." final Node singleSourceNode = XFormsUtils.getNodeFromNodeInfoConvert( (NodeInfo) collectionToBeUpdated.get(collectionToBeUpdated.size() - 1)); // TODO: check namespace handling might be incorrect. Should use copyElementCopyParentNamespaces() instead? final Node singleClonedNode = Dom4jUtils.createCopy(singleSourceNode); sourceNodes = Collections.singletonList(singleSourceNode); clonedNodesTemp = Collections.singletonList(singleClonedNode); } else { // There are explicitly specified origin objects // "The insert action is terminated with no effect if the origin node-set is the empty node-set." if (originItems.size() == 0) { if (indentedLogger != null && indentedLogger.isDebugEnabled()) indentedLogger.logDebug("xf:insert", "origin node-set is empty, terminating"); return Collections.EMPTY_LIST; } // "Each node in the origin node-set is cloned in the order it appears in the origin node-set." sourceNodes = new ArrayList<Node>(originItems.size()); // set to max possible size clonedNodesTemp = new ArrayList<Node>(originItems.size()); for (final Object currentObject : originItems) { if (currentObject instanceof NodeInfo) { // This is the regular case covered by XForms 1.1 / XPath 1.0 // NOTE: Don't clone nodes if doClone == false final Node sourceNode = XFormsUtils.getNodeFromNodeInfoConvert((NodeInfo) currentObject); final Node clonedNode = doClone ? (sourceNode instanceof Element) ? ((Element) sourceNode).createCopy() : (Node) sourceNode.clone() : sourceNode; sourceNodes.add(sourceNode); clonedNodesTemp.add(clonedNode); } else if (currentObject instanceof AtomicValue) { // This is an extension: support sequences containing atomic values // Convert the result to a text node final String stringValue = ((Item) currentObject).getStringValue(); final Text textNode = Dom4jUtils.createText(stringValue); sourceNodes.add(null); // there is no source node for this cloned node, it's a source item clonedNodesTemp.add(textNode); } else throw new IllegalStateException(); } } // Remove instance data from cloned nodes and perform Document node adjustment for (int i = 0; i < clonedNodesTemp.size(); i++) { final Node clonedNodeTemp = clonedNodesTemp.get(i); if (clonedNodeTemp instanceof Element) { // Element node InstanceData.remove(clonedNodeTemp); clonedNodeTemp.detach(); } else if (clonedNodeTemp instanceof Attribute) { // Attribute node InstanceData.remove(clonedNodeTemp); clonedNodeTemp.detach(); } else if (clonedNodeTemp instanceof Document) { // Document node final Element clonedNodeTempRootElement = clonedNodeTemp.getDocument().getRootElement(); if (clonedNodeTempRootElement == null) { // Can be null in rare cases of documents without root element clonedNodesTemp.set(i, null); // we support having a null node further below, so set this to null } else { InstanceData.remove(clonedNodeTempRootElement); // We can never really insert a document into anything at this point, but we assume that this means the root element clonedNodesTemp.set(i, clonedNodeTempRootElement.detach()); } } else { // Other nodes clonedNodeTemp.detach(); } } clonedNodes = clonedNodesTemp; } // "6. The target location of each cloned node or nodes is determined" // "7. The cloned node or nodes are inserted in the order they were cloned at their target location // depending on their node type." // Identify the instance that actually changes final XFormsInstance modifiedInstance; // Find actual insertion point and insert final NodeInfo insertLocationNodeInfo; final List<Node> insertedNodes; final String beforeAfterInto; if (isEmptyNodesetBinding) { // Insert INTO a node // "If the Node Set Binding node-set is not specified or empty, the insert location node is the insert // context node." // "a. If the Node Set Binding node-set is not specified or empty, the target location depends on the // node type of the cloned node. If the cloned node is an attribute, then the target location is before // the first attribute of the insert location node. If the cloned node is not an attribute, then the // target location is before the first child of the insert location node." modifiedInstance = (containingDocument != null) ? containingDocument.getInstanceForNode(insertContextNodeInfo) : null; insertLocationNodeInfo = insertContextNodeInfo; final Node insertLocationNode = XFormsUtils.getNodeFromNodeInfo(insertContextNodeInfo, CANNOT_INSERT_READONLY_MESSAGE); insertedNodes = doInsert(insertLocationNode, clonedNodes, modifiedInstance, doDispatch); beforeAfterInto = "into"; // Normalize text nodes if needed to respect XPath 1.0 constraint { boolean hasTextNode = false; for (Node clonedNode : clonedNodes) { hasTextNode |= clonedNode != null && clonedNode.getNodeType() == Node.TEXT_NODE; } if (hasTextNode) Dom4jUtils.normalizeTextNodes(insertLocationNode); } } else { // Insert BEFORE or AFTER a node insertLocationNodeInfo = (NodeInfo) collectionToBeUpdated.get(insertionIndex - 1); final Node insertLocationNode = XFormsUtils.getNodeFromNodeInfo(insertLocationNodeInfo, CANNOT_INSERT_READONLY_MESSAGE); modifiedInstance = (containingDocument != null) ? containingDocument.getInstanceForNode(insertLocationNodeInfo) : null; final Document insertLocationNodeDocument = insertLocationNode.getDocument(); if (insertLocationNodeDocument != null && insertLocationNodeDocument.getRootElement() == insertLocationNode) { // "c. if insert location node is the root element of an instance, then that instance root element // location is the target location. If there is more than one cloned node to insert, only the // first node that does not cause a conflict is considered." insertedNodes = doInsert(insertLocationNode.getDocument(), clonedNodes, modifiedInstance, doDispatch); beforeAfterInto = positionAttribute; // TODO: ideally normalize to "into document node"? // NOTE: Don't need to normalize text nodes in this case, as no new text node is inserted } else { // "d. Otherwise, the target location is immediately before or after the insert location // node, based on the position attribute setting or its default." if (insertLocationNode.getNodeType() == Node.ATTRIBUTE_NODE) { // Special case for "next to an attribute" // NOTE: In XML, attributes are unordered. dom4j handles them as a list so has order, but // the XForms spec shouldn't rely on attribute order. We could try to keep the order, but it // is harder as we have to deal with removing duplicate attributes and find a reasonable // insertion strategy. // TODO: Don't think we should even do this now in XForms 1.1 insertedNodes = doInsert(insertLocationNode.getParent(), clonedNodes, modifiedInstance, doDispatch); } else { // Other node types final Element parentNode = insertLocationNode.getParent(); final List<Node> siblingElements = Dom4jUtils.content(parentNode); final int actualIndex = siblingElements.indexOf(insertLocationNode); // Prepare insertion of new element final int actualInsertionIndex; if ("before".equals(positionAttribute)) { actualInsertionIndex = actualIndex; } else { // "after" actualInsertionIndex = actualIndex + 1; } // "7. The cloned node or nodes are inserted in the order they were cloned at their target // location depending on their node type." boolean hasTextNode = false; int addIndex = 0; insertedNodes = new ArrayList<Node>(clonedNodes.size()); for (Node clonedNode : clonedNodes) { if (clonedNode != null) {// NOTE: we allow passing some null nodes so we check on null if (!(clonedNode instanceof Attribute || clonedNode instanceof Namespace)) { // Element, text, comment, processing instruction node siblingElements.add(actualInsertionIndex + addIndex, clonedNode); insertedNodes.add(clonedNode); hasTextNode |= clonedNode.getNodeType() == Node.TEXT_NODE; addIndex++; } else { // We never insert attributes or namespace nodes as siblings if (indentedLogger != null && indentedLogger.isDebugEnabled()) indentedLogger.logDebug("xf:insert", "skipping insertion of node as sibling in element content", "type", clonedNode.getNodeTypeName(), "node", clonedNode instanceof Attribute ? Dom4jUtils.attributeToDebugString((Attribute) clonedNode) : clonedNode.toString()); } } } // Normalize text nodes if needed to respect XPath 1.0 constraint if (hasTextNode) Dom4jUtils.normalizeTextNodes(parentNode); } beforeAfterInto = positionAttribute; } } // Whether some nodes were inserted final boolean didInsertNodes = insertedNodes != null && insertedNodes.size() > 0; // Log stuff if (indentedLogger != null && indentedLogger.isDebugEnabled()) { if (didInsertNodes) indentedLogger.logDebug("xf:insert", "inserted nodes", "count", Integer.toString(insertedNodes.size()), "instance", (modifiedInstance != null) ? modifiedInstance.getEffectiveId() : null); else indentedLogger.logDebug("xf:insert", "no node inserted"); } // "XForms Actions that change the tree structure of instance data result in setting all four flags to true" if (didInsertNodes && modifiedInstance != null) { // NOTE: Can be null if document into which delete is performed is not in an instance, e.g. in a variable modifiedInstance.markModified(); modifiedInstance.model().markStructuralChange(modifiedInstance); } // Gather list of modified nodes final List<NodeInfo> insertedNodeInfos; if (didInsertNodes && modifiedInstance != null) { // Can be null if document into which delete is performed is not in an instance, e.g. in a variable final DocumentWrapper documentWrapper = (DocumentWrapper) modifiedInstance.documentInfo(); insertedNodeInfos = new ArrayList<NodeInfo>(insertedNodes.size()); for (Object insertedNode : insertedNodes) insertedNodeInfos.add(documentWrapper.wrap(insertedNode)); } else { insertedNodeInfos = Collections.emptyList(); } // "4. If the insert is successful, the event xforms-insert is dispatched." // XFormsInstance handles index and repeat items updates if (doDispatch && didInsertNodes && modifiedInstance != null) { // Adjust insert location node and before/after/into in case the root element was replaced final NodeInfo adjustedInsertLocationNodeInfo; final String adjustedBeforeAfterInto; final NodeInfo parent = insertedNodeInfos.get(0).getNodeKind() == org.w3c.dom.Node.ELEMENT_NODE ? insertedNodeInfos.get(0).getParent() : null; if (parent != null && parent.equals(parent.getDocumentRoot())) { // Node was inserted under document node adjustedInsertLocationNodeInfo = parent.getDocumentRoot(); adjustedBeforeAfterInto = "into"; } else { adjustedInsertLocationNodeInfo = insertLocationNodeInfo; adjustedBeforeAfterInto = beforeAfterInto; } Dispatch.dispatchEvent(new XFormsInsertEvent(modifiedInstance, insertedNodeInfos, originItems, adjustedInsertLocationNodeInfo, adjustedBeforeAfterInto)); } return insertedNodeInfos; }
From source file:org.orbeon.oxf.xforms.xbl.XBLTransformer.java
License:Open Source License
/** * Apply an XBL transformation, i.e. apply xbl:content, xbl:attr, etc. * * NOTE: This mutates shadowTreeDocument. *///from w ww .j av a 2 s . c om public static Document transform(final Document shadowTreeDocument, final Element boundElement, final boolean excludeNestedHandlers, final boolean excludeNestedLHHA) { final DocumentWrapper documentWrapper = new DocumentWrapper(boundElement.getDocument(), null, XPathCache.getGlobalConfiguration()); Dom4jUtils.visitSubtree(shadowTreeDocument.getRootElement(), new Dom4jUtils.VisitorListener() { boolean isNestedHandler(Element e) { return e.getParent() == boundElement && EventHandlerImpl.isEventHandler(e); } boolean isNestedLHHA(Element e) { return e.getParent() == boundElement && LHHA.isLHHA(e); } boolean mustFilterOut(Element e) { return excludeNestedHandlers && isNestedHandler(e) || excludeNestedLHHA && isNestedLHHA(e); } public void startElement(Element element) { // Handle xbl:content final boolean isXBLContent = element.getQName().equals(XBL_CONTENT_QNAME); final List<Node> resultingNodes; if (isXBLContent) { final String includesAttribute = element.attributeValue(XFormsConstants.INCLUDES_QNAME); final String scopeAttribute = element.attributeValue(XFormsConstants.XXBL_SCOPE_QNAME); final List<Node> contentToInsert; if (includesAttribute == null) { // All bound node content must be copied over (except nested handlers if requested) final List<Node> elementContent = Dom4jUtils.content(boundElement); final List<Node> clonedContent = new ArrayList<Node>(); for (final Node node : elementContent) { if (node instanceof Element) { final Element currentElement = (Element) node; if (!mustFilterOut(currentElement)) clonedContent.add(Dom4jUtils.copyElementCopyParentNamespaces(currentElement)); } else if (!(node instanceof Namespace)) { clonedContent.add(Dom4jUtils.createCopy(node)); } } contentToInsert = clonedContent; } else { // Apply CSS selector // Convert CSS to XPath final String xpathExpression = CSSParser.toXPath(includesAttribute); final NodeInfo boundElementInfo = documentWrapper.wrap(boundElement); // TODO: don't use getNamespaceContext() as this is already computed for the bound element final List<Object> elements = XPathCache.evaluate(boundElementInfo, xpathExpression, new NamespaceMapping(Dom4jUtils.getNamespaceContext(element)), null, null, null, null, null, null);// TODO: locationData if (elements.size() > 0) { // Clone all the resulting elements contentToInsert = new ArrayList<Node>(elements.size()); for (Object o : elements) { final NodeInfo currentNodeInfo = (NodeInfo) o; final Element currentElement = (Element) ((VirtualNode) currentNodeInfo) .getUnderlyingNode(); if (!mustFilterOut(currentElement)) contentToInsert.add(Dom4jUtils.copyElementCopyParentNamespaces(currentElement)); } } else { // Clone all the element's children if any // See: http://www.w3.org/TR/xbl/#the-content contentToInsert = new ArrayList<Node>(element.nodeCount()); for (Object o : element.elements()) { final Element currentElement = (Element) o; if (!mustFilterOut(currentElement)) contentToInsert.add(Dom4jUtils.copyElementCopyParentNamespaces(currentElement)); } } } // Insert content if any if (contentToInsert != null && contentToInsert.size() > 0) { final List<Node> parentContent = Dom4jUtils.content(element.getParent()); final int elementIndex = parentContent.indexOf(element); parentContent.addAll(elementIndex, contentToInsert); } // Remove <xbl:content> from shadow tree element.detach(); resultingNodes = contentToInsert; if (!StringUtils.isBlank(scopeAttribute)) { // If author specified scope attribute, use it setAttribute(resultingNodes, XFormsConstants.XXBL_SCOPE_QNAME, scopeAttribute, null); } else { // By default, set xxbl:scope="outer" on resulting elements setAttribute(resultingNodes, XFormsConstants.XXBL_SCOPE_QNAME, "outer", null); } } else { // Element is simply kept resultingNodes = Collections.singletonList((Node) element); } // Handle attribute forwarding final Attribute xblAttr = element.attribute(XBL_ATTR_QNAME); // standard xbl:attr (custom syntax) final Attribute xxblAttr = element.attribute(XXBL_ATTR_QNAME); // extension xxbl:attr (XPath expression) if (xblAttr != null) { // Detach attribute (not strictly necessary?) xblAttr.detach(); // Get attribute value final String xblAttrString = xblAttr.getValue(); final StringTokenizer st = new StringTokenizer(xblAttrString); while (st.hasMoreTokens()) { final String currentValue = st.nextToken(); final int equalIndex = currentValue.indexOf('='); if (equalIndex == -1) { // No a=b pair, just a single QName final QName valueQName = Dom4jUtils.extractTextValueQName(element, currentValue, true); if (!valueQName.getNamespaceURI().equals(XFormsConstants.XBL_NAMESPACE_URI)) { // This is not xbl:text, copy the attribute setAttribute(resultingNodes, valueQName, boundElement.attributeValue(valueQName), boundElement); } else { // This is xbl:text // "The xbl:text value cannot occur by itself in the list" } } else { // a=b pair final QName leftSideQName; { final String leftSide = currentValue.substring(0, equalIndex); leftSideQName = Dom4jUtils.extractTextValueQName(element, leftSide, true); } final QName rightSideQName; { final String rightSide = currentValue.substring(equalIndex + 1); rightSideQName = Dom4jUtils.extractTextValueQName(element, rightSide, true); } final boolean isLeftSideXBLText = leftSideQName.getNamespaceURI() .equals(XFormsConstants.XBL_NAMESPACE_URI); final boolean isRightSideXBLText = rightSideQName.getNamespaceURI() .equals(XFormsConstants.XBL_NAMESPACE_URI); final String rightSideValue; final Element namespaceElement; if (!isRightSideXBLText) { // Get attribute value rightSideValue = boundElement.attributeValue(rightSideQName); namespaceElement = boundElement; } else { // Get text value // "any text nodes (including CDATA nodes and whitespace text nodes) that are // explicit children of the bound element must have their data concatenated" rightSideValue = boundElement.getText();// must use getText() and not stringValue() namespaceElement = null; } if (rightSideValue != null) { // NOTE: XBL doesn't seem to says what should happen if the source attribute is not // found! We assume the rule is ignored in this case. if (!isLeftSideXBLText) { // Set attribute value setAttribute(resultingNodes, leftSideQName, rightSideValue, namespaceElement); } else { // Set text value // "value of the attribute on the right-hand side are to be represented as text // nodes underneath the shadow element" // TODO: "If the element has any child nodes in the DOM (any nodes, including // comment nodes, whitespace text nodes, or even empty CDATA nodes) then the pair // is in error and UAs must ignore it, meaning the attribute value is not forwarded" setText(resultingNodes, rightSideValue); } } } // TODO: handle xbl:lang? // TODO: handle type specifiers? } } else if (xxblAttr != null) { // Detach attribute (not strictly necessary?) xxblAttr.detach(); // Get attribute value final String xxblAttrString = xxblAttr.getValue(); final NodeInfo boundElementInfo = documentWrapper.wrap(boundElement); // TODO: don't use getNamespaceContext() as this is already computed for the bound element final List<Object> nodeInfos = XPathCache.evaluate(boundElementInfo, xxblAttrString, new NamespaceMapping(Dom4jUtils.getNamespaceContext(element)), null, null, null, null, null, null);// TODO: locationData if (nodeInfos.size() > 0) { for (Object nodeInfo : nodeInfos) { final NodeInfo currentNodeInfo = (NodeInfo) nodeInfo; if (currentNodeInfo.getNodeKind() == org.w3c.dom.Node.ATTRIBUTE_NODE) { // This is an attribute final Attribute currentAttribute = (Attribute) ((VirtualNode) currentNodeInfo) .getUnderlyingNode(); setAttribute(resultingNodes, currentAttribute.getQName(), currentAttribute.getValue(), currentAttribute.getParent()); } } } } // Prefix resulting xhtml:*/(@id |@for) // NOTE: We could also do the prefixing in the handlers, when the page is output. // // * Benefit of prefixing here: done statically // * Drawback of prefixing here: in the future if we try to reuse simple shadow trees this won't work // { // if (resultingNodes != null && resultingNodes.size() > 0) { // for (Iterator i = resultingNodes.iterator(); i.hasNext();) { // final Node node = (Node) i.next(); // if (node instanceof Element) { // Dom4jUtils.visitSubtree((Element) node, new Dom4jUtils.VisitorListener() { // public void startElement(Element element) { // if (XMLConstants.XHTML_NAMESPACE_URI.equals(element.getNamespaceURI())) { // // Found XHTML element // // // Update @id and @for if any // final Attribute idAttribute = element.attribute("id"); // if (idAttribute != null) { // idAttribute.setValue(prefix + idAttribute.getValue()); // } // final Attribute forAttribute = element.attribute("for"); // if (forAttribute != null) { // forAttribute.setValue(prefix + forAttribute.getValue()); // } // } // } // // public void endElement(Element element) { // } // // public void text(Text text) { // } // }); // } // } // } // } } private void setAttribute(List<Node> nodes, QName attributeQName, String attributeValue, Element namespaceElement) { if (nodes != null && nodes.size() > 0) { for (final Node node : nodes) { if (node instanceof Element) { final Element element = ((Element) node); // Copy missing namespaces, so that copying things like ref="foo:bar" work as expected Dom4jUtils.copyMissingNamespaces(namespaceElement, element); element.addAttribute(attributeQName, attributeValue); } } } } private void setText(List<Node> nodes, String value) { if (nodes != null && nodes.size() > 0) { for (final Node node : nodes) { if (node instanceof Element) { node.setText(value); } } } } public void endElement(Element element) { } public void text(Text text) { } }, true); return shadowTreeDocument; }
From source file:org.orbeon.oxf.xforms.XFormsUtils.java
License:Open Source License
/** * Return the underlying Node from the given NodeInfo, possibly converting it to a Dom4j Node. Changes to the returned Node may or may not * reflect on the original, depending on its type. * * @param nodeInfo NodeInfo to process * @return Node/* www .j a v a 2 s .c om*/ */ public static Node getNodeFromNodeInfoConvert(NodeInfo nodeInfo) { if (nodeInfo instanceof VirtualNode) return (Node) ((VirtualNode) nodeInfo).getUnderlyingNode(); else if (nodeInfo.getNodeKind() == org.w3c.dom.Node.ATTRIBUTE_NODE) { return Dom4jUtils.createAttribute( new QName(nodeInfo.getLocalPart(), new Namespace(nodeInfo.getPrefix(), nodeInfo.getURI())), nodeInfo.getStringValue()); } else return TransformerUtils.tinyTreeToDom4j( (nodeInfo.getParent() instanceof DocumentInfo) ? nodeInfo.getParent() : nodeInfo); }
From source file:org.zenonpagetemplates.onePhaseImpl.PageTemplateImpl.java
License:Open Source License
@SuppressWarnings({ "unchecked" }) private void defaultContent(Element element, ContentHandler contentHandler, LexicalHandler lexicalHandler, EvaluationHelper evaluationHelper, Stack<Map<String, Slot>> slotStack) throws SAXException, PageTemplateException, IOException, EvaluationException { // Use default template content for (Iterator<Node> i = element.nodeIterator(); i.hasNext();) { Node node = i.next();/*from ww w . j a va 2 s .c om*/ switch (node.getNodeType()) { case Node.ELEMENT_NODE: processElement((Element) node, contentHandler, lexicalHandler, evaluationHelper, slotStack); break; case Node.TEXT_NODE: char[] text = node.getText().toCharArray(); contentHandler.characters(text, 0, text.length); break; case Node.COMMENT_NODE: char[] comment = node.getText().toCharArray(); lexicalHandler.comment(comment, 0, comment.length); break; case Node.CDATA_SECTION_NODE: lexicalHandler.startCDATA(); char[] cdata = node.getText().toCharArray(); contentHandler.characters(cdata, 0, cdata.length); lexicalHandler.endCDATA(); break; case Node.NAMESPACE_NODE: Namespace declared = (Namespace) node; //System.err.println( "Declared namespace: " + declared.getPrefix() + ":" + declared.getURI() ); this.namespaces.put(declared.getPrefix(), declared.getURI()); //if ( declared.getURI().equals( TAL_NAMESPACE_URI ) ) { // this.talNamespacePrefix = declared.getPrefix(); //} //else if (declared.getURI().equals( METAL_NAMESPACE_URI ) ) { // this.metalNamespacePrefix = declared.getPrefix(); //} break; case Node.ATTRIBUTE_NODE: // Already handled break; case Node.DOCUMENT_TYPE_NODE: case Node.ENTITY_REFERENCE_NODE: case Node.PROCESSING_INSTRUCTION_NODE: default: //System.err.println( "WARNING: Node type not supported: " + node.getNodeTypeName() ); } } }
From source file:org.zenonpagetemplates.twoPhasesImpl.ZPTDocumentFactory.java
License:Open Source License
@SuppressWarnings({ "unchecked" }) static private void mapContent(Element element, ZPTElement zptElement, ZPTDocument zptDocument, Stack<Map<String, Slot>> slotStack) throws SAXException, PageTemplateException, IOException { // Use default template content for (Iterator<Node> i = element.nodeIterator(); i.hasNext();) { Node node = i.next();//www. j a v a 2 s. co m switch (node.getNodeType()) { case Node.ELEMENT_NODE: zptElement.addContent(getNewZPTElement((Element) node, zptDocument, slotStack)); break; case Node.TEXT_NODE: zptElement.addContent(new TextNode(node.getText())); break; case Node.CDATA_SECTION_NODE: zptElement.addContent(new CDATANode(node.getText())); break; case Node.NAMESPACE_NODE: // Already handled /* Namespace declared = (Namespace)node; if (zptDocument.isNamespaceToDeclare(declared)){ zptDocument.addNamespace(declared); } else { zptElement.addNamespaceStaticAttribute(declared); } break;*/ case Node.ATTRIBUTE_NODE: // Already handled case Node.COMMENT_NODE: // Remove all comments case Node.DOCUMENT_TYPE_NODE: case Node.ENTITY_REFERENCE_NODE: case Node.PROCESSING_INSTRUCTION_NODE: default: // Nothing to do } } }