Linq to XML
- See also, Linq: Operators
- 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 _namesConsole.WriteLine(_names[0]);
select new XStreamingElement("Name", n));
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