Download presentation
Presentation is loading. Please wait.
1
Extending System.Xml Ted Neward http://www.tedneward.com
2
XML in.NET.NET has tremendous XML support “out of the box” Both Infoset-based and stream-based parser support XPath navigation across Infosets Schema-to-object support XML Serialization … and so on
3
XML in.NET Despite this, sometimes it’s just not enough Working with XML in a strongly-typed language is awkward XSLT doesn’t have all the behavior we want We need to “reach out” from an XSLT to someplace else (database?) We want to “extend” XPath to other hierarchical storage (Registry? filesystem? database? XML database?) Fortunately, System.Xml provides for this
4
Extending System.Xml The.NET XML classes are highly extensible We’ll look at four ways to extend the XML support in.NET Extend XmlDocument and friends Extend XmlPathNavigator to navigate across other hierarchies Extend XmlReader/XmlWriter to produce/consume XML Extend XslTransform to include custom behavior
5
Extending XmlDocument XmlDocument is a concrete, non-sealed class LoadXml() parses XML into Infoset form Uses various CreateXXX() methods to create the Infoset tree Some methods are marked virtual for easy overriding Allow for creation of objects which can plug into Infoset tree
6
Extending XmlDocument Start with your basic Person public class Person { public string FirstName { get { return “Fred”; } } public string LastName { get { return “Wesley”; } } public override string ToString() { return FirstName + " " + LastName; }
7
Extending XmlDocument We want to create Persons from XML static void Main(string[] args) { XmlDocument doc = new XmlDocument(); string xml = " ” + “ Fred ” + “ Wesley ” + “ “; doc.LoadXml(xml); Person p = // ??? }
8
Extending XmlDocument Solution: Person IS-A XmlElement... class Person : XmlElement { internal Person(string prefix, string lname, string nsuri, XmlDocument doc) : base(prefix, lname, nsuri, doc) { } public string FirstName { get { return this["firstName"].InnerText; } } public string LastName { get { return this["lastName"].InnerText; } } public override string ToString() { return FirstName + " " + LastName; }
9
Extending XmlDocument... and we use a custom XmlDocument to create them class PersonDocument : XmlDocument { public override XmlElement CreateElement(string prefix, string lname, string nsuri) { if (lname=="person") return new Person(prefix, lname, nsuri, this); else return base.CreateElement(prefix, lname, nsuri); }
10
Extending XmlDocument... and now we can create Persons from XML static void Main() { string XML = // as before PersonDocument pdoc = new PersonDocument(); pdoc.LoadXml(XML); Person p = (Person)pdoc.DocumentElement; Console.WriteLine(p); }
11
Extending XmlDocument So what? We can already do XML-to-object-to-XML mappings with xsd.exe Why bother overriding XmlDocument? No schema definition required Flexible creation: what if we want to change types based on the XML? We want to work with both XML and type representations at once Allows for objects to be extensible; unrecognized elements (age? SSN?) are still part of Person, just not captured strongly Requires extending XmlElement (implementation inheritance)
12
Extending XPathNavigator XPathNavigator: abstract class providing XPath cursor Provides ability to execute XPath queries on hierarchical storage XPathDocument provides XPathNavigator for XmlDocument objects Extend XPathNavigator and override as necessary to provide customization (See Aaron Skonnard’s “XML Files” article in MSDN for examples) public static void Main() { XPathDocument doc = new XPathDocument("books.xml"); XPathNavigator nav = doc.CreateNavigator(); XPathNodeIterator ni = nav.Select("/bookstore/book/title"); while (ni.MoveNext()) Console.WriteLine(ni.Current.Value); }
13
Extending XPathNavigator So what? XPath provides powerful hierarchical query API Extend that to other hierarchical storage systems for ease-of-use Because XslTransform takes XPathNavigator as source argument, use custom XPathNavigator to do transforms on non-XML sources
14
Extending XmlReader/XmlWriter XmlReader and XmlWriter “Source” and “sink” for XML, respectively Abstract base classes with numerous abstract methods XmlTextReader and XmlTextWriter Derivatives of XmlReader and XmlWriter, respectively Specifically deal with producing/consuming XML from text streams Useful as templates for creating customized reader/writer classes
15
Extending XmlReader/XmlWriter So what? We have XmlTextReader/XmlTextWriter, what else do we need? XML may come in forms other than plain text encrypted compressed XML may come from other sources than files Fixed-length flat files CSV files XML could be processed entirely in-proc: no storage whatsoever
16
Extending XslTransform XslTransform does XSLT processing programmatically Create an XslTransform object Call Transform(), passing in source and output: public static void Main() { XslTransform xslt = new XslTransform(); XmlUrlResolver resolver = new XmlUrlResolver(); resolver.Credentials = new NetworkCredential("username","password","domain"); xslt.Load(“stylesheet.xsl", resolver); xslt.Transform(new XPathDocument("test.xml"), null, new XmlTextWriter(Console.Out), resolver); }
17
Extending XslTransform Two ways to add behavior to XSLT processing: Add extensions as “script” within XSLT stylesheet itself Add objects to XSLT arguments passed into Transform()
18
Extending XslTransform Add script extensions to stylesheet <xsl:stylesheet version=“1.0” xmlns:xsl=“...” xmlns:msxsl=“urn:schemas-microsoft-com:xslt” xmlns:ted=“http://www.clrgeeks.com/xsl-extensions”> public string Concat(string lhs, string rhs) { return lhs + “ “ + rhs; }
19
Extending XslTransform Add objects to argument list to Transform() First, create an “extension object”: methods will be called from XSLT public class Extension { public string Concat(string s1, string s2) { return s1 + " " + s2; } }
20
Extending XslTransform Add objects to argument list to Transform() Add extension objects to XsltArgumentList and pass to Transform() public static void Main() { XslTransform xslt = new XslTransform(); XsltArgumentList args = new XsltArgumentList(); Extension obj = new Extension(); args.AddExtensionObject("http://www.clrgeeks.com/Extension", obj); xslt.Load("extended.xsl", resolver); xslt.Transform(new XPathDocument("test.xml"), args, new XmlTextWriter(Console.Out), resolver); }
21
Extending XslTransform Add objects to argument list to Transform() Use the called method in the stylesheet <xsl:stylesheet version="1.0“ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ted="http://www.clrgeeks.com/Extension">
22
Extending XslTransform So what? XSLT has a lot of built-in behavior; what more do we need? Extensions can provide additional “reach” to XSLT database network (FTP, HTTP, WebServices/SOAP,...) other web services Extensions can also provide similar-yet-different behavior Such as concat-with-whitespace, concat-without-whitespace, etc. Best of both worlds: XSLT + the.NET FCL
23
Summary Extending System.Xml is a lot easier than you might think Look for ways to use this flexibility Custom XmlDocument types to provide type-safety and Infoset APIs Custom XPathNavigators to allow for easy access and XSLT transformation Custom XML sources and sinks Custom behavior in XSL transformations
24
Questions ?
25
Credentials Who is this guy? Independent consultant Author C# in a Nutshell (O’Reilly, with Drayton, Albahari, 2001) Server-Based Java Programming (Manning, 2000) SSCLI Essentials (O’Reilly, with Stutz, Shilling, 2003) Effective Enterprise Java (Addison-Wesley, 3Q 2003) Papers at http://www.neward.nethttp://www.neward.net Blog at http://blogs.tedneward.comhttp://blogs.tedneward.com
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.