Create XML Nodes based on XPath?

后端 未结 12 599
囚心锁ツ
囚心锁ツ 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:55

    The C# version of Mark Miller's Java solution

        /// 
        /// Makes the X path. Use a format like //configuration/appSettings/add[@key='name']/@value
        /// 
        /// The doc.
        /// The xpath.
        /// 
        public static XmlNode createNodeFromXPath(XmlDocument doc, string xpath)
        {
            // Create a new Regex object
            Regex r = new Regex(@"/+([\w]+)(\[@([\w]+)='([^']*)'\])?|/@([\w]+)");
    
            // Find matches
            Match m = r.Match(xpath);
    
            XmlNode currentNode = doc.FirstChild;
            StringBuilder currentPath = new StringBuilder();
    
            while (m.Success)
            {
                String currentXPath = m.Groups[0].Value;    // "/configuration" or "/appSettings" or "/add"
                String elementName = m.Groups[1].Value;     // "configuration" or "appSettings" or "add"
                String filterName = m.Groups[3].Value;      // "" or "key"
                String filterValue = m.Groups[4].Value;     // "" or "name"
                String attributeName = m.Groups[5].Value;   // "" or "value"
    
                StringBuilder builder = currentPath.Append(currentXPath);
                String relativePath = builder.ToString();
                XmlNode newNode = doc.SelectSingleNode(relativePath);
    
                if (newNode == null)
                {
                    if (!string.IsNullOrEmpty(attributeName))
                    {
                        ((XmlElement)currentNode).SetAttribute(attributeName, "");
                        newNode = doc.SelectSingleNode(relativePath);
                    }
                    else if (!string.IsNullOrEmpty(elementName))
                    {
                        XmlElement element = doc.CreateElement(elementName);
                        if (!string.IsNullOrEmpty(filterName))
                        {
                            element.SetAttribute(filterName, filterValue);
                        }
    
                        currentNode.AppendChild(element);
                        newNode = element;
                    }
                    else
                    {
                        throw new FormatException("The given xPath is not supported " + relativePath);
                    }
                }
    
                currentNode = newNode;
    
                m = m.NextMatch();
            }
    
            // Assure that the node is found or created
            if (doc.SelectSingleNode(xpath) == null)
            {
                throw new FormatException("The given xPath cannot be created " + xpath);
            }
    
            return currentNode;
        }
    

提交回复
热议问题