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
result = strip.Replace(fixedNamespaces, "", -1, pos);
#endregion
Powered by: newtelligence dasBlog 2.3.9074.18820
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2013, Patrick Cauldwell
E-mail