Presentation is loading. Please wait.

Presentation is loading. Please wait.

Extending System.Xml Ted Neward

Similar presentations


Presentation on theme: "Extending System.Xml Ted Neward"— Presentation transcript:

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


Download ppt "Extending System.Xml Ted Neward"

Similar presentations


Ads by Google