+
+ private static DataSchemaNode getDataSchemaNodeByXpath(final String parentNodeXpath,
+ final SchemaContext schemaContext) {
+ final String[] xpathNodeIdSequence = xpathToNodeIdSequence(parentNodeXpath);
+ return findDataSchemaNodeByXpathNodeIdSequence(xpathNodeIdSequence, schemaContext.getChildNodes());
+ }
+
+ private static String[] xpathToNodeIdSequence(final String xpath) {
+ final String[] xpathNodeIdSequence = Arrays.stream(xpath.split(XPATH_DELIMITER_REGEX))
+ .map(identifier -> identifier.replaceFirst(XPATH_NODE_KEY_ATTRIBUTES_REGEX, ""))
+ .filter(identifier -> !identifier.isEmpty())
+ .toArray(String[]::new);
+ if (xpathNodeIdSequence.length < 1) {
+ throw new DataValidationException("Invalid xpath.", "Xpath contains no node identifiers.");
+ }
+ return xpathNodeIdSequence;
+ }
+
+ private static DataSchemaNode findDataSchemaNodeByXpathNodeIdSequence(final String[] xpathNodeIdSequence,
+ final Collection<? extends DataSchemaNode> dataSchemaNodes) {
+ final String currentXpathNodeId = xpathNodeIdSequence[0];
+ final DataSchemaNode currentDataSchemaNode = dataSchemaNodes.stream()
+ .filter(dataSchemaNode -> currentXpathNodeId.equals(dataSchemaNode.getQName().getLocalName()))
+ .findFirst().orElseThrow(() -> schemaNodeNotFoundException(currentXpathNodeId));
+ if (xpathNodeIdSequence.length <= 1) {
+ return currentDataSchemaNode;
+ }
+ if (currentDataSchemaNode instanceof DataNodeContainer) {
+ return findDataSchemaNodeByXpathNodeIdSequence(
+ getNextLevelXpathNodeIdSequence(xpathNodeIdSequence),
+ ((DataNodeContainer) currentDataSchemaNode).getChildNodes());
+ }
+ throw schemaNodeNotFoundException(xpathNodeIdSequence[1]);
+ }
+
+ private static String[] getNextLevelXpathNodeIdSequence(final String[] xpathNodeIdSequence) {
+ final String[] nextXpathNodeIdSequence = new String[xpathNodeIdSequence.length - 1];
+ System.arraycopy(xpathNodeIdSequence, 1, nextXpathNodeIdSequence, 0, nextXpathNodeIdSequence.length);
+ return nextXpathNodeIdSequence;
+ }
+
+ private static DataValidationException schemaNodeNotFoundException(final String schemaNodeIdentifier) {
+ return new DataValidationException("Invalid xpath.",
+ String.format("No schema node was found for xpath identifier '%s'.", schemaNodeIdentifier));
+ }