"Raed Sawalha" <Ra*********@discussions.microsoft.com> wrote in message news:1E**********************************@microsof t.com...
the real problem i have that when created the element as following:
XmlElement elem = doc.CreateElement("imsmd:lom","x");
it is generated as
<imsmd:lom xmlns:imsmd="x">info</imsmd:lom>
but what i need is
<imsmd:lom>info</imsmd:lom>
how can I achieve this?
Martin's response is correct: the xmlns belongs there in XML with namespaces.
I have observed only a handful of application development areas (such as XML
editors and text processors), in which developers sometimes have an interest in
stripping out the extra xmlns declarations. For instance, they might be copying
the 'piece of text' they've gotten from OuterXml to somewhere else within the
same text stream, and they know the destination is already going to have the
necessary xmlns decls in-scope. Another example is maybe the application
is mapping an underlying XmlDocument node tree to the text representation
in an edit window, and they must pass a portion of text corresponding the
selected nodes to the DrawString( ) method in GDI+ to re-paint the invali-
dated part of the display.
One way to get around these xmlns declarations is just to strip out any xmlns,
like the following filtering StreamWriter subclass does,
- - - XmlNsFilterWriter.cs
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace Derek
{
/// <remarks>
/// XmlNsFilterWriter strips out all xmlns declarations present
/// in XML fragment string representations.
/// </remarks>
public class XmlNsFilterWriter : StreamWriter
{
protected Stream outs;
/// <summary>
/// Creates a filter to strip xmlns attributes around a stream that is an XML fragment.
/// </summary>
/// <param name='s'>
/// a sink to filter writes into.
/// </param>
public XmlNsFilterWriter( Stream s) : base( s)
{
outs = s;
}
/// <summary>
/// Eliminates occurrences of the substring " xmlns[:prefix]=/nsuri/" in the string
/// by advancing the cursor, p, past them.
/// </summary>
/// <param name='s'>
/// a well-formed XML string to filter.
/// </param>
/// <param name='p'>
/// a position index that is modified.
/// </param>
/// <throws cref='System.FormatException'>
/// an xmlns declaration was found but it was missing an expected quote delimiter.
/// </throws>
protected void filterXmlNs( string s, ref int p)
{
char quoteMark; // could be dbl or single.
p += 7; // strlen( " xmlns(:|=)") == 7.
try
{
while ( s[p] != '"' && s[p] != '\'' )
{
++p;
}
quoteMark = s[p];
while ( s[++p] != quoteMark )
{
;
}
++p;
}
catch ( IndexOutOfRangeException ioore)
{
Debug.Assert( false, "Closing xmlns quotation mark expected but" +
"not found in XmlNsFilterWriter.filterXmlNs( )");
throw new FormatException( "Bad xmlns syntax in output stream.", ioore);
}
}
public override void Write( string s)
{
StringBuilder sb = new StringBuilder( );
int pos = 0;
int len = s.Length;
int endOfSearchIdx = len - 7;
// Within 7 characters of end-of-string, finding
// an xmlns declaration is impossible.
//
while ( pos < endOfSearchIdx )
{
bool inTextContent = true;
// Don't look for " xmlns" between > and <, since
// it would be text content not an attribute value.
//
if ( !inTextContent && s[ pos] == '>' )
{
inTextContent = true;
}
else
{
// This would be < if it were intended
// to be in the text content.
//
if ( inTextContent && s[ pos] == '<' )
{
inTextContent = false;
}
}
// Check to see if this is the start of an xmlns
// attribute.
//
if ( !inTextContent && ( s.Substring( pos, 6).CompareTo( " xmlns") == 0 ) )
{
// Set pos 1 past closing quote.
//
filterXmlNs( s, ref pos);
}
sb.Append( s[ pos]);
++pos;
}
// Copy last zero to six chars.
sb.Append( s, pos, ( len - pos));
byte[] buf = new UTF8Encoding( ).GetBytes( sb.ToString( ));
outs.Write( buf, 0, buf.Length);
}
}
- - -
Now to print your XmlElement, elem, to the console without the xmlns but with any
prefix, you could write something like this,
XmlNsFilterWriter filter = new XmlNsFilterWriter( Console.OpenStandardOutput( ));
Console.SetOut( filter);
Console.Write( elem.OuterXml);
What this does is wrap the afforementioned StreamWriter around stdout (so every
output call going to stdout, or any other Stream you wrap XmlNsFilterWriter
around, passes through XmlNsFilterWriter). The overrides on certain methods
of StreamWriter in XmlNsFilterWriter keep track of state and pinpoint times when
the text "xmlns..." is being written out. All XmlNsFilterWriter does is eat those
chars, and pass the rest of the Stream through to your console undisturbed.
Note that this XmlNsFilterWriter is a little "strip-happy," in that it will strip all the
xmlns declarations. Occassionally, there may be some xmlns declarations you
want to keep. For instance, if the node is the top-level node in which that xmlns
first comes into scope, you may need its declaration. Handle this by checking
it's parent node to see if a namespace URI being removed is also in-scope on
the parent. If it is then it may be safe to take it from the child. If it's not then
the child is probably responsible for having the xmlns declaration.
Again, the actual number of real XML applications where something like this
applies are few and far between. Normally, you should want to keep the xmlns.
I'd be interested in hearing just what the application area is where you need the
xmlns taken out (as you can tell, I keep a list on this particular problem, and to
date it's a very short list).
Derek Harmon