且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何更改某些元素的XML名称空间

更新时间:2023-11-25 08:38:58

您可以将整个XML解析为一个字符串,并在适当的地方插入名称空间.但是,此解决方案可以创建仅在算法内使用的许多新字符串,这对性能不利.但是,我已经编写了一个以这种方式解析它的函数,对于您发布的示例XML来说,它似乎运行得非常快.如果您想使用它,我可以发布它.

You can just parse the whole XML as a string and insert namespaces where appropriate. This solution, however, can create lots of new strings only used within the algorithm, which is not good for the performance. However, I've written a function parsing it in this manner and it seems to run quite fast for sample XML you've posted ;). I can post it if you would like to use it.

另一种解决方案是将XML加载为 XmlDocument ,并且利用它是树状结构这一事实.这样,您可以创建一个在适当的地方递归添加适当的名称空间的方法.不幸的是, XmlNode.Name 属性是只读的,这就是为什么您必须手动复制xml的整个结构以更改某些节点的名称的原因.我现在没有时间编写代码,所以我只允许您编写它.如果您遇到任何问题,请告诉我.

Another solution is loading XML as XmlDocument and taking advantage of the fact it's a tree-like structure. This way, you can create a method recursively adding appropriate namespaces where appropriate. Unfortunately, XmlNode.Name attribute is read-only and that's why you have to manually copy the entire structure of the xml to change names of some nodes. I don't have time to write the code right now, so I just let you write it. If you encounter any issues with it, just let me know.

更新

我已经测试了您的代码和 Jeff Mercado 所建议的代码,而且它们似乎都可以正常工作,至少在您已在问题中发布的XML示例中.确保您要解析的XML与您发布的XML相同.

I've tested your code and code suggested by Jeff Mercado and both of them seem to work correctly, at least in the sample XML you've posted in the question. Make sure the XML you are trying to parse is the same as the one you've posted.

只是为了使其工作并解决最初提出的添加名称空间的问题,您可以使用代码,该代码将整个XML作为 String 处理并手动解析:

Just to make it work and solve adding namespace issue originally asked, you can use the code, which handles the whole XML as a String and parses it manually:

private static String UpdateNodesWithDefaultNamespace(String xml, String defaultNamespace)
    {
        if (!String.IsNullOrEmpty(xml) && !String.IsNullOrEmpty(defaultNamespace))
        {
            int currentIndex = 0;

            while (currentIndex != -1)
            {
                //find index of tag opening character
                int tagOpenIndex = xml.IndexOf('<', currentIndex);

                //no more tag openings are found
                if (tagOpenIndex == -1)
                {
                    break;
                }

                //if it's a closing tag
                if (xml[tagOpenIndex + 1] == '/')
                {
                    currentIndex = tagOpenIndex + 1;
                }
                else
                {
                    currentIndex = tagOpenIndex;
                }

                //find corresponding tag closing character
                int tagCloseIndex = xml.IndexOf('>', tagOpenIndex);
                if (tagCloseIndex <= tagOpenIndex)
                {
                    throw new Exception("Invalid XML file.");
                }

                //look for a colon within currently processed tag
                String currentTagSubstring = xml.Substring(tagOpenIndex, tagCloseIndex - tagOpenIndex);
                int firstSpaceIndex = currentTagSubstring.IndexOf(' ');
                int nameSpaceColonIndex;
                //if space was found
                if (firstSpaceIndex != -1)
                {
                    //look for namespace colon between tag open character and the first space character
                    nameSpaceColonIndex = currentTagSubstring.IndexOf(':', 0, firstSpaceIndex);
                }
                else
                {
                    //look for namespace colon between tag open character and tag close character
                    nameSpaceColonIndex = currentTagSubstring.IndexOf(':');
                }

                //if there is no namespace
                if (nameSpaceColonIndex == -1)
                {
                    //insert namespace after tag opening characters '<' or '</'
                    xml = xml.Insert(currentIndex + 1, String.Format("{0}:", defaultNamespace));
                }

                //look for next tags after current tag closing character
                currentIndex = tagCloseIndex;
            }
        }

        return xml;
    }

您可以签出此代码以使您的应用正常运行,但是,我强烈建议您确定为什么建议的其他解决方案不起作用.

You can check this code out in order to make you app working, however, I strongly encourage you to determine why the other solutions suggested didn't work.