Я знаю, что это действительно старая тема ... но я только что попробовал ту же самую вещь и придумал следующее регулярное выражение, которое не идеально, но я считаю более общим
/+([\w]+)(\[@([\w]+)='([^']*)'\])?|/@([\w]+)
Строка / configuration / appSettings / add [@ key = 'name'] / @ value
должно быть проанализировано до
Найдено 14 совпадений:
начало = 0, конец = 14
Группа (0) = / конфигурация
Группа (1) = конфигурация
Группа (2) = ноль
Группа (3) = ноль
Группа (4) = ноль
Группа (5) = ноль
начало = 14, конец = 26
Group (0) = / appSettings
Group (1) = appSettings
Группа (2) = ноль
Группа (3) = ноль
Группа (4) = ноль
Группа (5) = ноль
начало = 26, конец = 43
Group (0) = / add [@ key = 'name']
Группа (1) = добавить
Группа (2) = [@ key = 'name']
Группа (3) = ключ
Группа (4) = имя
Группа (5) = ноль
начало = 43, конец = 50
Группа (0) = / @ значение
Группа (1) = ноль
Группа (2) = ноль
Группа (3) = ноль
Группа (4) = ноль
Группа (5) = значение
Что означает, что у нас есть
группа (0) = игнорируется
Группа (1) = Имя элемента
Группа (2) = Игнорируется
Группа (3) = имя атрибута фильтра
Группа (4) = Значение атрибута фильтра
Вот метод Java, который может использовать шаблон
public static Node createNodeFromXPath(Document doc, String expression) throws XPathExpressionException {
StringBuilder currentPath = new StringBuilder();
Matcher matcher = xpathParserPattern.matcher(expression);
Node currentNode = doc.getFirstChild();
while (matcher.find()) {
String currentXPath = matcher.group(0);
String elementName = matcher.group(1);
String filterName = matcher.group(3);
String filterValue = matcher.group(4);
String attributeName = matcher.group(5);
StringBuilder builder = currentPath.append(currentXPath);
String relativePath = builder.toString();
Node newNode = selectSingleNode(doc, relativePath);
if (newNode == null) {
if (attributeName != null) {
((Element) currentNode).setAttribute(attributeName, "");
newNode = selectSingleNode(doc, relativePath);
} else if (elementName != null) {
Element element = doc.createElement(elementName);
if (filterName != null) {
element.setAttribute(filterName, filterValue);
}
currentNode.appendChild(element);
newNode = element;
} else {
throw new UnsupportedOperationException("The given xPath is not supported " + relativePath);
}
}
currentNode = newNode;
}
if (selectSingleNode(doc, expression) == null) {
throw new IllegalArgumentException("The given xPath cannot be created " + expression);
}
return currentNode;
}