miercuri, 20 ianuarie 2010

Linq to XML

Linq to XML





  • Functional construction: term used to describe the ability to construct an entire XML hierarchy in a single statement
  • namespace System.Xml.Linq.
  • Linq to XML API is very element centric (dif. from document centric)
  • document centricity eliminated in favor of element centricity
    • in W3C DOM: attributes, comments, CData, section, processing instruction, elements must be created from XmlDocument
  • System.Xml.XmlConvert
    • .ToBoolean()



  • The only classes that could have nodes derived from XNode are XDocument and XElement
  • Halloween problem:
    • there is any problem that occurs by changing data that is being iterated over affect the iteration
    • it can occur, for example, when removing elements from an XML tree
      • solution: move elements that are removed in a cache list
  • XDocument _doc = new XDocument();
    XmlWriter _writer = _doc.CreateWriter();
    XslCompiledTransform _transform = new XslCompiledTransfor();
  • IEnumerable<XElement> _elements = new Element[]
    { new XElement("Element" , "Element A")
    , new XElement("Element" , "Element B") };
    XElement _root = new XElement("Root" ,
    _elements.Select(e => string(e) != "Element A" ? new Element(e.Name, (string)e) : null));
    • null - it is used to do not create an XElement - ignore the iteration

Components

XDocument


  • XML Documents are not a must anymore (to create attributes, comments, ... )
  • You can read, save a doc without needing a Document object
  • Namespaces are out
    • inside, no longer exists
  • IEnumerable<XElements> _members = xDocument.Element("Team StatViewer").Elements("Member");
  • XDocument _doc = new XDocument(
    new XDeclaration("1.0", "UTF-8", "yes")
    , new XDocumentType("StatViewer", null, "StatViewer.dtd", null)
    , new XProcessingInstruction("Team StatViewer", "to be printed")
    , new XElement ( "Team StatViewer"));
  • .Save()
  • .SaveOptions.DisableFormatting
  • .Load()

XName

  • consist of
    • namespace (XNamespace)
    • local name (LocalName)
  • there is no need to directly create a name
    • has no public ctor
  • XNamespace _namespace = "http://www.ixiacom.com";
  • XElement _member = new XElement(_namespace + "Member");

XElement

  • XElement _team = new XElement ( "Team StatViewer" 
                                 , new XElement ("Name" , "George Lache")
                                 , new XElement ("Position" , "Senior Dev"));
  • _team.ToString();
  • calling .ToString() method of an element outputs the XML string itself and not object type
    • XElement _george = new XElement ("Name" , "George Lache");
      //"Name" is a XName
      //"George Lache is a XText
      Console.WriteLine(_george); // <Name>George Lache</Name>
      Console.WriteLine((string)_george); // George Lache
      - return a XText
  • XElement _team = new XElement ( "Team StatViewer"
    ,  members.Select ( m =>
    new XElement("Member",
    new XAttribute("Position" , m.Position),
    new XElement("Name", m.Name)));
  • .Add(XAttribute), .Add(XComment)
  • .Save()
  • .Load()
  • .LoadOptions
    • .Name
    • .PreserveWhitespace
    • .SetLineInfo //set line & position
      • IXmlLineInfo
      • ((IXmlLineInfo)name)
        • .LineNumber
        • .LinePosition
    • SetBaseUri()
  • .Parse()
    • used for parsing XML string
    • XElement.Parse(_xmlText);
  • .AncestorsAndSelf();
  • DescendantsAndSelf();


XComment


  • creates comments
  • XElement _member = ...;
    XComment _comm = new XComment("This is StatViewer team presentation");
    _member.Add(_comm);


XCData

  • CData content
  • XCData _cData = new XCData("<h1>Invalidate member</h1>"
    , "<elem>!CData[<h1> .... </h1>] </elem>")

XNode


  • it is an abstract class - cannot be instantiated
  • subclasses: XComment, XContainer, XDocumentType, XProcessingInstruction, XText
  • .NextNode()
    • traverse forward
  • .PreviousNode()
    • traverse barward
  • .Ancestors()
    • recursively traverses up the XML tree
  • .NodesAfterSelf()
    • traversing forward the current node
  • .ElementsAfterSelf()
  • .NodesBeforeSelf()
  • .ElementsBeforeSelf()

XStreamingElement


  • defers elecution of the XML tree construction
  • when you create an XML tree using XStreamingElement, a reference to the query variable is stored in the XML tree without being iterated.
  • string _names = {"George Lache", "Anca Suciu", "Marian Gheorghe"};
    XStreamingElement members = new XStreamingElement("Members",
    from n in _names
    select new XStreamingElement("Name", n));
    Console.WriteLine(_names[0]);

XText

  • XText _text = new XText("George Lache");

XObject


  • .Document
    • obtains the XML Document
  • .Parent
  • .AddAnnotation()
  • .Annotation()
  • .Annotations()
  • .RemoveAnnotations()

XContainer

  • Represents a node that can contain other nodes.
  • This class provides functionality such as finding the next or previous sibling node, or enumerating the direct children of a node.
  • The two classes that derive from XContainer are XDocument and XElement
  • .Nodes()
    • _doc.Nodes().OfType<XElement>
  • .Attributes()
  • .Elements()
    • accessing an element's child elements
  • Element()
    • _member.Element("Name");
  • .Elements()
  • .Descendants();
  • .Add()
  • .AddLast()
  • .AddFirst()

How to change an XML?


  • XElement
    • .SetElementValue()
    • .RemoveAll()
      • deletes the content of an element, but not he element itself
    • .Value
      • also, for XText, XComment
      • _member.Element("Name").Single().Name = "George";
    • .ReplaceAll()
      • replaces an element's entire subtree of XML
    • SetElementValue()
      • it is a method on a parent element to affect its content (child elements)
      • if you pass null the child elements will be removed
      • it will affect only the first child element that matches the specified name
      • Sample:
        _member.SetElementValue("Name", "George V. Lache");
      • it can be used for adding/updating/removing an element
    • .Attribute()
    • .Attributes()
    • .Add()
    • .AddFirst()
    • .AddBeforeThis()
    • .AddAfterThis()
    • .AddAttributeValue()
  • XContainer: .Add(), .AddLast(), .AddFirst()
  • XNode:
    • .AddBeforeSelf()
      • inserts a node into a node's list of child nodes in a specific location
    • .AddAfterSelf(),
    • .Remove()
      • Remove any node as well as its child nodes and its attributes from an XML tree
      • _members.Descendants().Where(m => m.Name.Contains("George")).Remove();
  • XDocumentType
    • .Name
      • update document type
    • .PublicId // "http:// ... .DTD"
    • .SystemId
  • XProcessingInstruction
    • Sample: new XProcessingInstruction("Team StatViewer", "to be printed")
    • .Target //"Team StatViewer"
    • .Data //"to be printed"
  • XAttribude
    • does not inherit from XNode
    • .FirstAttribute()
    • .LastAttribute()
    • .NextAttribute()
    • .PreviousAttibute()
    • .Remove()
      • IEnumerable<T>.Remove()
      • _member.Attributes().Remove()
    • to update:
      • .Value
      • .SetAttributeValue()
        • also, used for updating and deleting

XML Annotation


  • provides the ability to associate a user data object with any class inheriting from XObject class via annotations
    • assigns whatever data type to an element, document, ...
  • XObject
    • .AddAnnotation()
    • .Annotation()
    • .Annotations()
    • .RemoveAnnotations()
  • Sample:
    MemberClass _memberClass = new MemberClass();
    _memberElement.AddAnnotation(_
    memberClass);
    _memberElement.GetAnnotation<MemberClass>();
    _memberElement.RemoveAnnotation<MemberClass>();


XML Events

  • the events will be raised on the object if that object or any descendant object is changing
  • XObject
    • .Changing
      • myXObj.Changing = new EventHandler<XObjectChangeEventArgs>(MyHandlingMethod);
    • Changed
  • XObjectChangeEventArgs
    • .ObjectChange
      • of type XObjectChange
        • .Add
        • .Name
        • .Remove
        • .Value
  • !!! when you change the string value of an element, an XText object is removed and then added back

Linq to XML Operators


  • Xml Operators
    • are extension methods
    • are defined in System.Xml.Linq.Extension class
  • extension methods are somehow equivalent to operators
  • Element
    • IEnumerable<XElement> Element<T>
                (this IEnumerable<T> source)
      where T : XElement
  • Ancestors
    • IEnumerable<XElement> Ancestors<T>
                 (this IEnumerable<T> source)
      [,Xname name)]
                 where T : XNode
    • _xDoc.Element("Members").Descendand("Name").Ancestors()
  • AncestorsAndSelf
    • it can be called on XElement
      • as opposed to Ancestor which is called on Node
  • Attributes
    • retrives a sequence containint the attributes of each source element
  • DescendantNodes
    • return a sequence containing the descendant nodes if each element or document
    • public static IEnumerable<Xnode> DescendingNodes<T>
                                   (this IEnumerable<T> source)
                         where T : XContainer
  • DescendantNodesAndSelf
  • Descendants
    • can be called on a sequence of elements or documents and return a sequence of elements
  • DescendantsAndSelf
  • Elements
    • returns a sequence of elements containing each source element's or document's child element
    • returns only the immediate child elements of each element in the source sequence
  • InDocumentOrder
    • returns a sequence containing each source node's child nodes in document order
  • Nodes
    • returns only the immediate child elements
    • public static IEnumerable<Xnode> Nodes<T>
                                   (this IEnumerable<T> source)
                         where T : XContainer
  • Remove

Validation


  • in system.Xml.Schema.Extension
  • .Validate
    • (this XDocument [or XElement or XAttribure] source,
      XmlSchemeSet schemas,
      ValidationEventHandler validationEH)
      [,bool addShemaInfo)]
  • .GetSchemaInfo
  • XmlSchemaValidationException

How to obtain an XML Schema (XSD schema file (.xsd))?

XmlSchemaInference inference = new XmlSchemaInference();
XmlSchemaSet schemaSet = inference.InferSchema ( new XmlTextReader ("StatViewer.xml") );
XmlWriter writer = XmlWriter.Create("StatViewer.xsd");
foreach(XmlSchema schema in schemaSet.Schemas)
{
    schema.Write(writer);
}

xDocument.Validate(schemaSet,
    (o , validExceptArgs ) =>
        {
            Console.WriteLine(o.GetType().Name +validExceptArgs.Message);
        });

XPath

  • XPath allows you to create a query by assembling a number of expressions and predicates, each one acting on a node-set 
  • XPathNavigator
  • System.Xml.XPath.Extension class
  • .CreateNavigator
    (this XNode node
    [, XmlNameTable nameTable])
  • XPathEvaluate()
  • XPathSelectElement()
  • XPathSelectElements()
  • Sample:
    • xDocument.XPathSelectElement("//StatViewer/Members/Member[Name = 'George Lache']")

Niciun comentariu:

Trimiteți un comentariu