Last active
July 30, 2017 20:37
-
-
Save tomvit/1428469 to your computer and use it in GitHub Desktop.
Create elements and/or an attribute or a text node along a path in xml.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Create elements and/or an attribute or a text node along a path in xml. | |
* Examples: let root be a xml element | |
* <foo/> | |
* | |
* To create a sub-element bar with an attribute id set to a value '5': | |
* Node n = createXmlPath(root, "/foo/bar/@id", "5"); | |
* | |
* To create a sub-element bar with a text content set to a value '7': | |
* Node n = createXmlPath(root, "/foo/bar/text()", "7); | |
* | |
* To create an empty sub-element bar | |
* Node n = createXmlPath(root, "/foo/bar", null); | |
* | |
* @param root element under which new elements and/or text or attribute nodes will be created. | |
* @param xpath xpath expression, must be in a form as examples show. | |
* @param nodeValue Value for a text node or an attribute if present at the end of the path. | |
* @return The last element on the path. | |
* @throws XPathExpressionException | |
*/ | |
public static Node createXmlPath(Element root, String xpath, String nodeValue) throws XPathExpressionException { | |
// try to select nodes according to xpath | |
XPath xp = XPathFactory.newInstance().newXPath(); | |
NodeList ns = (NodeList) xp.evaluate(xpath, root, XPathConstants.NODESET); | |
Node n = ns.getLength() > 0 ? ns.item(0) : null; | |
// create elements if the expression returns zero nodes | |
if (n == null) { | |
// parse the expression - get the last element from the xpath | |
String pattern = "(.*)/([A-Za-z0-9\\-_\\(\\)@]+)$"; | |
Pattern p = Pattern.compile(pattern); | |
Matcher m = p.matcher(xpath); | |
if (m.matches()) { | |
// recursive call - create the elements on the path that does not include the last element | |
Node pn = createXmlPath(root, m.group(1), null); | |
// if the last element is a text node, | |
// create the text node and set its value to nodeValue | |
if (m.group(2).equals("text()")) { | |
n = root.getOwnerDocument().createTextNode(nodeValue != null ? nodeValue : "__"); | |
pn.appendChild(n); | |
n = pn; | |
} else | |
// if the last element is attribute, | |
// create the attribute and set its value to nodeValue | |
if (m.group(2).matches("@[A-Za-z\\-_0-9]+")) { | |
Node a = root.getOwnerDocument().createAttribute(m.group(2).substring(1)); | |
a.setNodeValue(nodeValue != null ? nodeValue : "__"); | |
pn.getAttributes().setNamedItem(a); | |
n = pn; | |
} else { | |
// otherwise create normal element | |
n = root.getOwnerDocument().createElement(m.group(2)); | |
pn.appendChild(n); | |
} | |
} else | |
throw new XPathExpressionException("XPath expression must match the pattern '" + pattern + "'!"); | |
} | |
return n; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I was trying to get this to work but was out of luck.Is there a working sample.Any inputs would be of great help