# Thursday, 30 June 2005

I finally solved the namespace issue I was having, although I’ll probably burn for all eternity for the solution.  In short, because of the behavior of XmlTextWriter, the only solution that could be implemented in a reasonable amount of time was to post-process the XML and strip out the extra namespace declarations. 

So I started down the path of using XmlTextReader to spin through and collect up all the namespaces that I needed, then add those to the root node.  After that I could use a regular expression to strip out all the unneeded ones.  Turns out I had overlooked the fact that the input isn’t guaranteed to be well-formed XML.  :-(

The “XML” is actually a template that our system uses to do some tag replacement.  So the output of that process is well-formed, but the input can contain the “@” character inside element names.  A no-no according to the XML spec. 

So here it is, the all-regular-expression solution.  I wouldn’t suggest you try this at home, but it does actually work, and seems to be quite fast (sub 1/4 second for a 1.5Mb input, and the typical input is more like 10K). 

Note: this is made a little simpler because I know (since I just wrote out the “XML”) that all the namespace prefixes we care about start with ns, e.g. ns0, ns1, etc.

                    #region begin hairy namespace rectifying code here

                    //this is necessary because the XmlTextWriter puts in more namespace

                    //declarations than we want, which causes file bloat.

 

                    Regex strip = new Regex(@"xmlns\:ns\d=""[^""]*""");

                    ArrayList names = new ArrayList();

                    MatchCollection matches = strip.Matches(result);

                    foreach(Match match in matches)

                    {

                        string val = match.Value;

                        if(!val.StartsWith("xmlns:ns0"))

                            if(!names.Contains(match.Value))

                                names.Add(match.Value);

                    }

 

                    string fixedNamespaces = null;

                    StringBuilder sb = new StringBuilder();

                    foreach(string name in names)

                    {

                        sb.AppendFormat(" {0}",name);

                    }

 

                    fixedNamespaces = result;

 

                    int pos = fixedNamespaces.IndexOf(">",0);//should be the end of the xml declaration

                    pos = fixedNamespaces.IndexOf(">",pos+1);//should be end of root node.

 

                    fixedNamespaces = fixedNamespaces.Insert(pos,sb.ToString());

 

                    pos = fixedNamespaces.IndexOf(">",0);//should be the end of the xml declaration

                    pos = fixedNamespaces.IndexOf(">",pos+1);//should be end of root node.

                    result = strip.Replace(fixedNamespaces, "", -1, pos);

 

                    #endregion

XML
Wednesday, 06 July 2005 12:30:39 (Pacific Daylight Time, UTC-07:00)
This is what happens when you abuse namespace mixing:
http://thescourge.blogsome.com/2005/07/04/hipster-zombies-versus-knights-of-the-nerd-table/

So, please, next time you are thinking of throwing a <zombie:brainhunt /> into your <sca:sweatfest />, please, stop and think about the survivors, and how hard it is to clean up admixed mangled history buffs from semi-decomposed supernal flesh-eaters. Or something like that.

-T
Trey
Comments are closed.