List of usage examples for org.apache.commons.jxpath.ri.parser XPathParserConstants SLASH
int SLASH
To view the source code for org.apache.commons.jxpath.ri.parser XPathParserConstants SLASH.
Click Source Link
From source file:org.fao.geonet.kernel.EditLib.java
private boolean createAndAddFromXPath(Element metadataRecord, MetadataSchema metadataSchema, String xpathProperty, AddElemValue value) throws Exception { if (xpathProperty.startsWith("/")) { xpathProperty = xpathProperty.substring(1); }/* ww w . j av a 2s . co m*/ if (xpathProperty.startsWith(metadataRecord.getQualifiedName() + "/")) { xpathProperty = xpathProperty.substring(metadataRecord.getQualifiedName().length() + 1); } List<String> xpathParts = Arrays.asList(xpathProperty.split("/")); Pair<Element, String> result = findLongestMatch(metadataRecord, metadataRecord, 0, metadataSchema, xpathParts.size() / 2, xpathParts); final Element elementToAttachTo = result.one(); final Element clonedMetadata = (Element) elementToAttachTo.clone(); // Creating the element at the xpath location // Walk the XPath from the start until the end or the start of a filter // expression. // Collect element namespace prefix and name, check element exist and // create them according to schema definition. final XPathParser xpathParser = new XPathParser( new StringReader(clonedMetadata.getQualifiedName() + "/" + result.two())); // Start from the root of the metadata document Token currentToken = xpathParser.getNextToken(); Token previousToken = currentToken; int depth = 0; Element currentNode = clonedMetadata; boolean existingElement = true; boolean isAttribute = false; String currentElementName = ""; String currentElementNamespacePrefix = ""; // Stop when token is null, start of an expression is found ie. "[" // // Stop when an expression [ starts // The expression is supposed to be part of the XML snippet to insert // If an existing element needs to be updated use the _Xref_replace mode // this mode is more precise with the geonet:element/@ref. while (currentToken != null && currentToken.kind != 0 && currentToken.kind != XPathParserLocalConstants.SQBRACKET_OPEN) { // TODO : check no .., descendant, ... are in the xpath // Only full xpath are supported. if (XPathParserLocalConstants.ILLEGAL_KINDS.contains(currentToken.kind)) { return false; } // build element name as the parser progress into the xpath ... if (currentToken.kind == XPathParserLocalConstants.ATTRIBUTE) { isAttribute = true; } // Match namespace prefix if (currentToken.kind == XPathParserLocalConstants.TEXT && previousToken.kind == XPathParserConstants.SLASH) { // get element namespace if element is text and previous was / // means qualified name only is supported currentElementNamespacePrefix = currentToken.image; } else if (currentToken.kind == XPathParserLocalConstants.TEXT && previousToken.kind == XPathParserLocalConstants.NAMESPACE_SEP) { // get element name if element is text and previous was / currentElementName = currentToken.image; // Do not change anything to the root of the // metadata record which MUST be the root of // the xpath if (depth > 0) { // If an element name is created // Check the element exist in the metadata // and create it if needed. String qualifiedName = currentElementNamespacePrefix + ":" + currentElementName; if (Log.isDebugEnabled(Geonet.EDITORADDELEMENT)) { Log.debug(Geonet.EDITORADDELEMENT, "Check if " + qualifiedName + " exists in " + currentNode.getName()); } Element nodeToCheck = currentNode.getChild(currentElementName, Namespace.getNamespace(metadataSchema.getNS(currentElementNamespacePrefix))); if (nodeToCheck != null) { if (Log.isDebugEnabled(Geonet.EDITORADDELEMENT)) { Log.debug(Geonet.EDITORADDELEMENT, " > " + qualifiedName + " found"); } // Element found, no need to create it, continue walking the xpath. currentNode = nodeToCheck; existingElement &= true; } else { if (Log.isDebugEnabled(Geonet.EDITORADDELEMENT)) { Log.debug(Geonet.EDITORADDELEMENT, " > add new node " + qualifiedName + " inserted in " + currentNode.getName()); } if (metadataSchema.getElementValues(qualifiedName, currentNode.getQualifiedName()) != null) { currentNode = addElement(metadataSchema, currentNode, qualifiedName); existingElement = false; } else { // element not in schema so stop! return false; } } } depth++; // Reset current element props currentElementName = ""; currentElementNamespacePrefix = ""; } previousToken = currentToken; currentToken = xpathParser.getNextToken(); } // The current node is an existing node or newly created one // Insert the XML value // TODO: deal with attribute ? if (value.isXml()) { // If current node match the node name to insert // Insert the new node in its parent if (existingElement) { currentNode = addElement(metadataSchema, currentNode.getParentElement(), currentNode.getQualifiedName()); } // clean before update // when adding the fragment child nodes or suggestion may also be added. // In this case, the snippet only has to be inserted currentNode.removeContent(); doAddFragmentFromXpath(value.getNodeValue(), currentNode); } else { if (isAttribute) { currentNode.setAttribute(previousToken.image, value.getStringValue()); } else { currentNode.setText(value.getStringValue()); } } // update worked so now we can update original element... elementToAttachTo.removeContent(); List<Content> toAdd = Lists.newArrayList(clonedMetadata.getContent()); for (Content content : toAdd) { elementToAttachTo.addContent(content.detach()); } return true; }