[quoted text, click to view] "Victor Hadianto" <synop@nospam.nospam> wrote in message news:29545D69-FB25-4B5E-8B93-6C242714A0DC@microsoft.com...
> Is there a way (without using Regex) to find out if I already have the <?mso
> ...?> on the document?
There are at least three ways to find out if there's a processing instruction
in an XmlDocument that is (or starts with) "mso".
1. The method Oleg already posted is to use the XPath function,
processing-instruction( ). I'll add that if you want to find all PIs
starting with "mso", you'd use the following XPath expression,
//processing-instruction()[starts-with(local-name(),'mso')]
because the local-name() of a PI in XPath corresponds to the
PI's target.
2. Enumerate the DOM nodes of the document and when you
find a node with a NodeType of XmlNodeType.ProcessingInstruction
then you can examine it's LocalName and Value properties to get it's
target and pseudo-attributes, respectively.
- - - PiDomSearch.cs (excerpt)
// . . .
public void Descend( XmlNode node)
{
if ( null != node )
{
if ( XmlNodeType.ProcessingInstruction == node.NodeType )
{
if ( node.LocalName.StartsWith( "mso"))
{
// ... do something here ...
}
}
this.Descend( node.FirstChild);
this.Descend( node.NextSibling);
}
return;
}
// . . .
this.Descend( xmlDoc.DocumentElement);
// . . .
- - -
3. The prior techniques may be appealing if you're already traversing
the DOM node tree of an XmlDocument, but if you want the information
a priori then I think the best method is to use a specialized XmlReader
when loading the XmlDocument that would be responsible for detecting
the presence of these processing instructions,
- - - PiReaderSearch.cs (excerpt)
using System;
using System.Collections;
using System.IO;
using System.Xml;
// . . .
/// <summary>
/// <b>XmlTextReader</b> subclass that detects the presence of processing-instructions
/// as it reads an incoming <b>TextReader</b> whose targets start with a given text string.
/// </summary>
public class ProcInstXmlTextReader : XmlTextReader
{
private string piTarget;
private ArrayList matches;
private bool listening;
public ProcInstXmlTextReader( TextReader reader, string piTarget) : base( reader)
{
this.piTarget = piTarget;
this.matches = new ArrayList( );
}
public int MatchCount
{
get
{
return matches.Count;
}
}
public override XmlNodeType NodeType
{
get
{
this.intercepting = ( XmlNodeType.ProcessingInstruction == base.NodeType );
return base.NodeType;
}
}
public override string Name
{
get
{
string tgt = base.Name;
if ( this.intercepting )
{
if ( tgt.StartsWith( this.piTarget))
{
this.matches.Add( tgt);
this.intercepting = false;
}
}
return tgt;
}
}
}
// . . .
ProcInstXmlTextReader pixtr = new ProcInstTextReader(
new StreamReader( "filename.xml"), "mso"
);
xmlDoc.Load( pixtr);
if ( pixtr.MatchesCount > 0 )
{
// Process xmlDoc knowing that mso* PIs are present.
}
else
{
// Process xmlDoc knowing that it contains no mso* PIs.
}
// . . .
- - -
These examples presume you're looking for processing instructions that
start with the leading characters, "mso" (working with Microsoft Office
XML), but they're also easily adapted to testing for equality to "mso" if
you're looking for only one specific processing instruction target.
Derek Harmon