Create XML Nodes based on XPath?

后端 未结 12 668
囚心锁ツ
囚心锁ツ 2020-11-27 15:36

Does anyone know of an existing means of creating an XML hierarchy programatically from an XPath expression?

For example if I have an XML fragment such as:

12条回答
  •  悲哀的现实
    2020-11-27 15:39

    I know this is a really old thread ... but I have just been trying the same thing and came up with the following regex which is not perfect but I find more generic

    /+([\w]+)(\[@([\w]+)='([^']*)'\])?|/@([\w]+)
    

    The string /configuration/appSettings/add[@key='name']/@value

    should be parsed to

    Found 14 match(es):

    start=0, end=14 Group(0) = /configuration Group(1) = configuration Group(2) = null Group(3) = null Group(4) = null Group(5) = null

    start=14, end=26 Group(0) = /appSettings Group(1) = appSettings Group(2) = null Group(3) = null Group(4) = null Group(5) = null

    start=26, end=43 Group(0) = /add[@key='name'] Group(1) = add Group(2) = [@key='name'] Group(3) = key Group(4) = name Group(5) = null

    start=43, end=50 Group(0) = /@value Group(1) = null Group(2) = null Group(3) = null Group(4) = null Group(5) = value


    Which means we have

    Group(0) = Ignored Group(1) = The element name Group(2) = Ignored Group(3) = Filter attribute name Group(4) = Filter attribute value

    Here is a java method which can use the pattern

    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;
    

    }

提交回复
热议问题