cmdlet for search with a xpath expression within xml documents

Topics: Developer Forum
Developer
Jan 15, 2007 at 1:22 PM
Hello,

I have created a cmdlet for searching with a xpath expression within xml structures. As an input of the cmdlet you have to enter the xpath expression and, if needed, the xml namespaces.

here is the code:
---------------------------------------------------------------------------------
//---------------------------------------------------------------------
// Author: Mark Maier
//
// Description: Class to implement the Find-Xml cmdlet.
//
// Creation Date: Jan 9, 2007
//
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Management.Automation;
using System.Security;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using Pscx.Commands.Internal;

namespace Pscx.Commands.Xml
{
Cmdlet(PscxVerbs.Find, PscxNouns.Xml, DefaultParameterSetName = ParameterSetPath)
Description("Find elements in XML files and XmlDocument objects with XPath expressions.")
RelatedLinks ("Format-Xml")
RelatedLinks("Convert-Xml")
RelatedLinks("Test-Xml")
public class FindXmlCommand : XmlCommandBase
{
private string _xpathExpression;
private string[] _xmlNamespaces;

Parameter(HelpMessage = "XPath expression for finding elements",Mandatory = true)
public string XPath
{
get { return _xpathExpression; }
set { _xpathExpression = value; }
}

Parameter(HelpMessage = @"Array of XML namespaces like ""prefix;uri""")
public string[] XmlNamespaces
{
get { return _xmlNamespaces; }
set { _xmlNamespaces = value; }
}

protected override XmlReaderSettings XmlReaderSettings
{
get
{
XmlReaderSettings settings = base.XmlReaderSettings;
settings.ConformanceLevel = ConformanceLevel.Auto;

return settings;
}
}

protected override XmlWriterSettings XmlWriterSettings
{
get
{
XmlWriterSettings settings = base.XmlWriterSettings;
settings.ConformanceLevel = ConformanceLevel.Auto;

return settings;
}
}

protected override void ProcessXmlReader(XmlReader xmlReader, XmlWriter xmlWriter)
{
try
{
while (!xmlReader.EOF)
{
XPathDocument xpathDocument = new XPathDocument(xmlReader);
XPathExpression xpathExpression = XPathExpression.Compile(this._xpathExpression);
XmlNamespaceManager xmlNamespaceMgr = new XmlNamespaceManager(xmlReader.NameTable);

if (_xmlNamespaces != null)
{
foreach (string xmlNamespace in _xmlNamespaces)
{
string[] tmp = xmlNamespace.Split(new char[] { ';' });

xmgr.AddNamespace(tmp0, tmp1);
}
}

xpathExpression.SetContext(xmlNamespaceMgr);

XPathNavigator xpathNavigator = xpathDocument.CreateNavigator();
XPathNodeIterator nodes = xpathNavigator.Select(xpathExpression);

while (nodes.MoveNext())
{
xmlWriter.WriteNode(nodes.Current, false);
}
}

}
catch (Exception ex)
{
ErrorHandler.WriteXmlError(ex);
}
}
}
}
---------------------------------------------------------------------------------

As an example you can use it for doing something like this:

xml $( cat OIO_Invoice.xml) | find-xml -XPath "//com:TaxTotal" -XmlNamespaces "com;http://rep.oio.dk/ubl/xml/schemas/0p71/common/"


Greetings,

Mark Maier
Developer
Jan 15, 2007 at 3:16 PM
nice! i'd prefer calling it rather Select-Xml, to be consistent with powershell naming.

may i check it in, or do you want to do it yourself once Keith gives you access?
Developer
Jan 15, 2007 at 4:17 PM
What do I have to do for getting access?
Should I post in the Project Management Forum?

Thanks,

Mark
Developer
Jan 15, 2007 at 4:51 PM
I think the posting in here is sufficient. Just wait util Keith is online.
Coordinator
Jan 15, 2007 at 9:03 PM
Nice! You've been added to the project. I agree with Jachym in that Select-Xml would probably be a more PoSh like cmdlet name. Could you send me your email address so I can add you to my PSCX distribution list. My email address is rkeithhill@mailhot.comnospam_I. You'll need to unscramble that email address.

I wonder if I should check that list in? Right now, there isn't a good way for one PSCX developer to email all the other PSCX developers.
Coordinator
Jan 15, 2007 at 9:05 PM
Hmm, the forum post at the underscores in my email adress. It should be r-keith-hill where the hyphens are actually underscores in my email address.
Coordinator
Jan 16, 2007 at 4:19 AM
I wonder if using an equal for prefix/namespace would be a better separator e.g.:

com=http://schemas.acme.com/foo/bar/2007
Jan 17, 2007 at 4:01 AM
RE: the underscores...

The forum posts support wiki formatting. To type something that isn't formatted use the following syntax:

source:
{"r_keith_hill"}

output:
r_keith_hill