diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json index 5c736920fe5e8..583457d06a0df 100644 --- a/.openpublishing.redirection.json +++ b/.openpublishing.redirection.json @@ -1984,6 +1984,26 @@ "redirect_url": "/dotnet/standard/linq/remove-elements-attributes-nodes-xml-tree", "redirect_document_id": true }, + { + "source_path": "docs/csharp/programming-guide/concepts/linq/atomized-xname-and-xnamespace-objects-linq-to-xml.md", + "redirect_url": "/dotnet/standard/linq/atomized-xname-xnamespace-objects", + "redirect_document_id": true + }, + { + "source_path": "docs/csharp/programming-guide/concepts/linq/linq-to-xml-annotations.md", + "redirect_url": "/dotnet/standard/linq/linq-xml-annotations", + "redirect_document_id": true + }, + { + "source_path": "docs/csharp/programming-guide/concepts/linq/pre-atomization-of-xname-objects-linq-to-xml.md", + "redirect_url": "/dotnet/standard/linq/pre-atomization-xname-objects", + "redirect_document_id": true + }, + { + "source_path": "docs/csharp/programming-guide/concepts/linq/statically-compiled-queries-linq-to-xml.md", + "redirect_url": "/dotnet/standard/linq/statically-compiled-queries", + "redirect_document_id": true + }, { "source_path": "docs/csharp/programming-guide/concepts/threading/how-to-use-a-thread-pool.md", "redirect_url": "/dotnet/api/system.threading.threadpool.queueuserworkitem" @@ -5631,6 +5651,26 @@ "redirect_url": "/dotnet/standard/linq/remove-elements-attributes-nodes-xml-tree", "redirect_document_id": false }, + { + "source_path": "docs/visual-basic/programming-guide/concepts/linq/atomized-xname-and-xnamespace-objects-linq-to-xml.md", + "redirect_url": "/dotnet/standard/linq/atomized-xname-xnamespace-objects", + "redirect_document_id": false + }, + { + "source_path": "docs/visual-basic/programming-guide/concepts/linq/linq-to-xml-annotations.md", + "redirect_url": "/dotnet/standard/linq/linq-xml-annotations", + "redirect_document_id": false + }, + { + "source_path": "docs/visual-basic/programming-guide/concepts/linq/pre-atomization-of-xname-objects-linq-to-xml.md", + "redirect_url": "/dotnet/standard/linq/pre-atomization-xname-objects", + "redirect_document_id": false + }, + { + "source_path": "docs/visual-basic/programming-guide/concepts/linq/statically-compiled-queries-linq-to-xml.md", + "redirect_url": "/dotnet/standard/linq/statically-compiled-queries", + "redirect_document_id": false + }, { "source_path": "docs/visual-basic/programming-guide/concepts/threading/how-to-use-a-thread-pool.md", "redirect_url": "/dotnet/api/system.threading.threadpool.queueuserworkitem" diff --git a/docs/csharp/programming-guide/concepts/linq/atomized-xname-and-xnamespace-objects-linq-to-xml.md b/docs/csharp/programming-guide/concepts/linq/atomized-xname-and-xnamespace-objects-linq-to-xml.md deleted file mode 100644 index 2bb3c8c42c103..0000000000000 --- a/docs/csharp/programming-guide/concepts/linq/atomized-xname-and-xnamespace-objects-linq-to-xml.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "Atomized XName and XNamespace Objects (LINQ to XML) (C#)" -ms.date: 07/20/2015 -ms.assetid: a5b21433-b49d-415c-b00e-bcbfb0d267d7 ---- -# Atomized XName and XNamespace Objects (LINQ to XML) (C#) - and objects are *atomized*; that is, if they contain the same qualified name, they refer to the same object. This yields performance benefits for queries: When you compare two atomized names for equality, the underlying intermediate language only has to determine whether the two references point to the same object. The underlying code does not have to do string comparisons, which would be time consuming. - -## Atomization Semantics - Atomization means that if two objects have the same local name, and they are in the same namespace, they share the same instance. In the same way, if two objects have the same namespace URI, they share the same instance. - - For a class to enable atomized objects, the constructor for the class must be private, not public. This is because if the constructor were public, you could create a non-atomized object. The and classes implement an implicit conversion operator to convert a string into an or . This is how you get an instance of these objects. You cannot get an instance by using a constructor, because the constructor is inaccessible. - - and also implement the equality and inequality operators, to determine whether the two objects being compared are references to the same instance. - -## Example - The following code creates some objects and demonstrates that identical names share the same instance. - -```csharp -XElement r1 = new XElement("Root", "data1"); -XElement r2 = XElement.Parse("data2"); - -if ((object)r1.Name == (object)r2.Name) - Console.WriteLine("r1 and r2 have names that refer to the same instance."); -else - Console.WriteLine("Different"); - -XName n = "Root"; - -if ((object)n == (object)r1.Name) - Console.WriteLine("The name of r1 and the name in 'n' refer to the same instance."); -else - Console.WriteLine("Different"); -``` - - This example produces the following output: - -```output -r1 and r2 have names that refer to the same instance. -The name of r1 and the name in 'n' refer to the same instance. -``` - - As mentioned earlier, the benefit of atomized objects is that when you use one of the axis methods that take an as a parameter, the axis method only has to determine that two names reference the same instance to select the desired elements. - - The following example passes an to the method call, which then has better performance because of the atomization pattern. - -```csharp -XElement root = new XElement("Root", - new XElement("C1", 1), - new XElement("Z1", - new XElement("C1", 2), - new XElement("C1", 1) - ) -); - -var query = from e in root.Descendants("C1") - where (int)e == 1 - select e; - -foreach (var z in query) - Console.WriteLine(z); -``` - - This example produces the following output: - -```xml -1 -1 -``` diff --git a/docs/csharp/programming-guide/concepts/linq/pre-atomization-of-xname-objects-linq-to-xml.md b/docs/csharp/programming-guide/concepts/linq/pre-atomization-of-xname-objects-linq-to-xml.md deleted file mode 100644 index 32ef1b3ef502f..0000000000000 --- a/docs/csharp/programming-guide/concepts/linq/pre-atomization-of-xname-objects-linq-to-xml.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: "Pre-Atomization of XName Objects (LINQ to XML) (C#)" -ms.date: 07/20/2015 -ms.assetid: e84fbbe7-f072-4771-bfbb-059d18e1ad15 ---- -# Pre-Atomization of XName Objects (LINQ to XML) (C#) -One way to improve performance in LINQ to XML is to pre-atomize objects. Pre-atomization means that you assign a string to an object before you create the XML tree by using the constructors of the and classes. Then, instead of passing a string to the constructor, which would use the implicit conversion from string to , you pass the initialized object. - - This improves performance when you create a large XML tree in which specific names are repeated. To do this, you declare and initialize objects before you construct the XML tree, and then use the objects instead of specifying strings for the element and attribute names. This technique can yield significant performance gains if you are creating a large number of elements (or attributes) with the same name. - - You should test pre-atomization with your scenario to decide if you should use it. - -## Example - The following example demonstrates this. - -```csharp -XName Root = "Root"; -XName Data = "Data"; -XName ID = "ID"; - -XElement root = new XElement(Root, - new XElement(Data, - new XAttribute(ID, "1"), - "4,100,000"), - new XElement(Data, - new XAttribute(ID, "2"), - "3,700,000"), - new XElement(Data, - new XAttribute(ID, "3"), - "1,150,000") -); - -Console.WriteLine(root); -``` - - This example produces the following output: - -```xml - - 4,100,000 - 3,700,000 - 1,150,000 - -``` - - The following example shows the same technique where the XML document is in a namespace: - -```csharp -XNamespace aw = "http://www.adventure-works.com"; -XName Root = aw + "Root"; -XName Data = aw + "Data"; -XName ID = "ID"; - -XElement root = new XElement(Root, - new XAttribute(XNamespace.Xmlns + "aw", aw), - new XElement(Data, - new XAttribute(ID, "1"), - "4,100,000"), - new XElement(Data, - new XAttribute(ID, "2"), - "3,700,000"), - new XElement(Data, - new XAttribute(ID, "3"), - "1,150,000") -); - -Console.WriteLine(root); -``` - - This example produces the following output: - -```xml - - 4,100,000 - 3,700,000 - 1,150,000 - -``` - - The following example is more similar to what you will likely encounter in the real world. In this example, the content of the element is supplied by a query: - -```csharp -XName Root = "Root"; -XName Data = "Data"; -XName ID = "ID"; - -DateTime t1 = DateTime.Now; -XElement root = new XElement(Root, - from i in System.Linq.Enumerable.Range(1, 100000) - select new XElement(Data, - new XAttribute(ID, i), - i * 5) -); -DateTime t2 = DateTime.Now; - -Console.WriteLine("Time to construct:{0}", t2 - t1); -``` - - The previous example performs better than the following example, in which names are not pre-atomized: - -```csharp -DateTime t1 = DateTime.Now; -XElement root = new XElement("Root", - from i in System.Linq.Enumerable.Range(1, 100000) - select new XElement("Data", - new XAttribute("ID", i), - i * 5) -); -DateTime t2 = DateTime.Now; - -Console.WriteLine("Time to construct:{0}", t2 - t1); -``` - -## See also - -- [Atomized XName and XNamespace Objects (LINQ to XML) (C#)](./atomized-xname-and-xnamespace-objects-linq-to-xml.md) diff --git a/docs/csharp/programming-guide/concepts/linq/statically-compiled-queries-linq-to-xml.md b/docs/csharp/programming-guide/concepts/linq/statically-compiled-queries-linq-to-xml.md deleted file mode 100644 index d6aaf54420837..0000000000000 --- a/docs/csharp/programming-guide/concepts/linq/statically-compiled-queries-linq-to-xml.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: "Statically Compiled Queries (LINQ to XML) (C#)" -ms.date: 07/20/2015 -ms.assetid: 3bf558fe-0705-479d-86d4-00188f5fcf9c ---- -# Statically Compiled Queries (LINQ to XML) (C#) -One of the most important performance benefits LINQ to XML, as opposed to , is that queries in LINQ to XML are statically compiled, whereas XPath queries must be interpreted at run time. This feature is built in to LINQ to XML, so you do not have to perform extra steps to take advantage of it, but it is helpful to understand the distinction when choosing between the two technologies. This topic explains the difference. - -## Statically Compiled Queries vs. XPath - The following example shows how to get the descendant elements with a specified name, and with an attribute with a specified value. - - The following is the equivalent XPath expression: `//Address[@Type='Shipping']` - -```csharp -XDocument po = XDocument.Load("PurchaseOrders.xml"); - -IEnumerable list1 = - from el in po.Descendants("Address") - where (string)el.Attribute("Type") == "Shipping" - select el; - -foreach (XElement el in list1) - Console.WriteLine(el); -``` - - The query expression in this example is re-written by the compiler to method-based query syntax. The following example, which is written in method-based query syntax, produces the same results as the previous one: - -```csharp -XDocument po = XDocument.Load("PurchaseOrders.xml"); - -IEnumerable list1 = - po - .Descendants("Address") - .Where(el => (string)el.Attribute("Type") == "Shipping"); - -foreach (XElement el in list1) - Console.WriteLine(el); -``` - - The method is an extension method. For more information, see [Extension Methods](../../classes-and-structs/extension-methods.md). Because is an extension method, the query above is compiled as though it were written as follows: - -```csharp -XDocument po = XDocument.Load("PurchaseOrders.xml"); - -IEnumerable list1 = - System.Linq.Enumerable.Where( - po.Descendants("Address"), - el => (string)el.Attribute("Type") == "Shipping"); - -foreach (XElement el in list1) - Console.WriteLine(el); -``` - - This example produces exactly the same results as the previous two examples. This illustrates the fact that queries are effectively compiled into statically linked method calls. This, combined with the deferred execution semantics of iterators, improves performance. For more information about the deferred execution semantics of iterators, see [Deferred Execution and Lazy Evaluation in LINQ to XML (C#)](./deferred-execution-and-lazy-evaluation-in-linq-to-xml.md). - -> [!NOTE] -> These examples are representative of the code that the compiler might write. The actual implementation might differ slightly from these examples, but the performance will be the same or similar to these examples. - -## Executing XPath Expressions with XmlDocument - The following example uses to accomplish the same results as the previous examples: - -```csharp -XmlReader reader = XmlReader.Create("PurchaseOrders.xml"); -XmlDocument doc = new XmlDocument(); -doc.Load(reader); -XmlNodeList nl = doc.SelectNodes(".//Address[@Type='Shipping']"); -foreach (XmlNode n in nl) - Console.WriteLine(n.OuterXml); -reader.Close(); -``` - - This query returns the same output as the examples that use LINQ to XML; the only difference is that LINQ to XML indents the printed XML, whereas does not. - - However, the approach generally does not perform as well as LINQ to XML, because the method must do the following internally every time it is called: - -- It parses the string that contains the XPath expression, breaking the string into tokens. - -- It validates the tokens to make sure that the XPath expression is valid. - -- It translates the expression into an internal expression tree. - -- It iterates through the nodes, appropriately selecting the nodes for the result set based on the evaluation of the expression. - - This is significantly more than the work done by the corresponding LINQ to XML query. The specific performance difference varies for different types of queries, but in general LINQ to XML queries do less work, and therefore perform better, than evaluating XPath expressions using . diff --git a/docs/visual-basic/programming-guide/concepts/linq/atomized-xname-and-xnamespace-objects-linq-to-xml.md b/docs/standard/linq/atomized-xname-xnamespace-objects.md similarity index 58% rename from docs/visual-basic/programming-guide/concepts/linq/atomized-xname-and-xnamespace-objects-linq-to-xml.md rename to docs/standard/linq/atomized-xname-xnamespace-objects.md index bcfdcfb189c58..3fdb16ac167fd 100644 --- a/docs/visual-basic/programming-guide/concepts/linq/atomized-xname-and-xnamespace-objects-linq-to-xml.md +++ b/docs/standard/linq/atomized-xname-xnamespace-objects.md @@ -1,25 +1,46 @@ --- -title: "Atomized XName and XNamespace Objects (LINQ to XML)" +title: Atomized XName and XNamespace objects - LINQ to XML +description: Learn how atomized XName and XNamespace objects of the same name share an instance. ms.date: 07/20/2015 -ms.assetid: 21ee7585-7df9-40b4-8c76-a12bb5f29bb3 +dev_langs: + - "csharp" + - "vb" +ms.assetid: a5b21433-b49d-415c-b00e-bcbfb0d267d7 --- -# Atomized XName and XNamespace Objects (LINQ to XML) (Visual Basic) +# Atomized XName and XNamespace objects (LINQ to XML) - and objects are *atomized*; that is, if they contain the same qualified name, they refer to the same object. This yields performance benefits for queries: When you compare two atomized names for equality, the underlying intermediate language only has to determine whether the two references point to the same object. The underlying code does not have to do string comparisons, which would be time consuming. + and objects are *atomized*; that is, if they contain the same qualified name, they refer to the same object. This yields performance benefits for queries: when you compare two atomized names for equality, the underlying intermediate language only has to determine whether the two references point to the same object. The underlying code doesn't have to do string comparisons, which would take longer. -## Atomization Semantics +## Atomization semantics -Atomization means that if two objects have the same local name, and they are in the same namespace, they share the same instance. In the same way, if two objects have the same namespace URI, they share the same instance. +Atomization means that if two objects have the same local name, and they're in the same namespace, they share the same instance. In the same way, if two objects have the same namespace URI, they share the same instance. -For a class to enable atomized objects, the constructor for the class must be private, not public. This is because if the constructor were public, you could create a non-atomized object. The and classes implement an implicit conversion operator to convert a string into an or . This is how you get an instance of these objects. You cannot get an instance by using a constructor, because the constructor is inaccessible. +For a class to enable atomized objects, the constructor for the class must be private, not public. This is because if the constructor were public, you could create a non-atomized object. The and classes implement an implicit conversion operator to convert a string into an or . This is how you get an instance of these objects. You can't get an instance by using a constructor, because the constructor is inaccessible. - and also implement the equality and inequality operators, to determine whether the two objects being compared are references to the same instance. + and also implement the equality and inequality operators, which determine whether the two objects being compared are references to the same instance. -## Example +## Example: Create objects and show that identical names share an instance The following code creates some objects and demonstrates that identical names share the same instance. +```csharp +XElement r1 = new XElement("Root", "data1"); +XElement r2 = XElement.Parse("data2"); + +if ((object)r1.Name == (object)r2.Name) + Console.WriteLine("r1 and r2 have names that refer to the same instance."); +else + Console.WriteLine("Different"); + +XName n = "Root"; + +if ((object)n == (object)r1.Name) + Console.WriteLine("The name of r1 and the name in 'n' refer to the same instance."); +else + Console.WriteLine("Different"); +``` + ```vb Dim r1 As New XElement("Root", "data1") Dim r2 As XElement = XElement.Parse("data2") @@ -41,7 +62,7 @@ End If This example produces the following output: -```console +```output r1 and r2 have names that refer to the same instance. The name of r1 and the name in 'n' refer to the same instance. ``` @@ -50,6 +71,23 @@ As mentioned earlier, the benefit of atomized objects is that when you use one o The following example passes an to the method call, which then has better performance because of the atomization pattern. +```csharp +XElement root = new XElement("Root", + new XElement("C1", 1), + new XElement("Z1", + new XElement("C1", 2), + new XElement("C1", 1) + ) +); + +var query = from e in root.Descendants("C1") + where (int)e == 1 + select e; + +foreach (var z in query) + Console.WriteLine(z); +``` + ```vb Dim root As New XElement("Root", New XElement("C1", 1), New XElement("Z1", New XElement("C1", 2), New XElement("C1", 1))) @@ -66,7 +104,3 @@ This example produces the following output: 1 1 ``` - -## See also - -- [Performance (LINQ to XML) (Visual Basic)](performance-linq-to-xml.md) diff --git a/docs/standard/linq/chain-standard-query-operators-together.md b/docs/standard/linq/chain-standard-query-operators-together.md index 5918db65ab0fc..ca3ad77753124 100644 --- a/docs/standard/linq/chain-standard-query-operators-together.md +++ b/docs/standard/linq/chain-standard-query-operators-together.md @@ -19,7 +19,7 @@ One difference is that in this case, the However, the basic idea is the same: intermediate collections aren't materialized unless they have to be. -When query expressions are used, they are converted to calls to the standard query operators, and the same principles apply. +When query expressions are used, they're converted to calls to the standard query operators, and the same principles apply. All of the examples in this section that are querying Office Open XML documents use the same principle. Deferred execution and lazy evaluation are some of the fundamental concepts that you must understand to use LINQ, and LINQ to XML, effectively. diff --git a/docs/standard/linq/create-source-office-open-xml-document.md b/docs/standard/linq/create-source-office-open-xml-document.md index 94a33b998b469..98875a6feb6b3 100644 --- a/docs/standard/linq/create-source-office-open-xml-document.md +++ b/docs/standard/linq/create-source-office-open-xml-document.md @@ -69,7 +69,7 @@ Use the following steps to create the WordprocessingML document: 1. Save the document, and name it SampleDoc.docx. > [!NOTE] -> If you are using Microsoft Word 2003, select **Word 2007 Document** in the **Save as Type** drop-down list. +> If you're using Microsoft Word 2003, select **Word 2007 Document** in the **Save as Type** drop-down list. ## See also diff --git a/docs/standard/linq/create-xml-trees.md b/docs/standard/linq/create-xml-trees.md index 76b5e4fb356cd..7281703b0e09f 100644 --- a/docs/standard/linq/create-xml-trees.md +++ b/docs/standard/linq/create-xml-trees.md @@ -39,7 +39,7 @@ If indented properly, the code to construct obje ## XElement constructors -The class uses the following constructors for functional construction. Note that there are some other constructors for , but because they aren't used for functional construction they aren't listed here. +The class uses the following constructors for functional construction. Note that there are some other constructors for , but because they're not used for functional construction they're not listed here. |Constructor|Description| |-----------------|-----------------| diff --git a/docs/standard/linq/filter-optional-element.md b/docs/standard/linq/filter-optional-element.md index 139deeeda531e..e3c21fab48ee2 100644 --- a/docs/standard/linq/filter-optional-element.md +++ b/docs/standard/linq/filter-optional-element.md @@ -10,7 +10,7 @@ ms.assetid: f99e2f93-fca5-403f-8a0c-770761d4905a # How to filter on an optional element (LINQ to XML) -Sometimes you want to filter for an element even though you aren't sure it exists in your XML document. You can write your search so that, even if the particular element doesn't have the child element, you don't trigger a null reference exception by filtering for it. +Sometimes you want to filter for an element even though you're not sure it exists in your XML document. You can write your search so that, even if the particular element doesn't have the child element, you don't trigger a null reference exception by filtering for it. ## Example: Search that doesn't trigger an exception when the target element doesn't exist diff --git a/docs/standard/linq/in-memory-xml-tree-modification-vs-functional-construction.md b/docs/standard/linq/in-memory-xml-tree-modification-vs-functional-construction.md index d6fd532cb28ed..00dda94d761a3 100644 --- a/docs/standard/linq/in-memory-xml-tree-modification-vs-functional-construction.md +++ b/docs/standard/linq/in-memory-xml-tree-modification-vs-functional-construction.md @@ -14,7 +14,7 @@ Modifying an XML tree in place is a traditional approach to changing the shape o LINQ to XML enables another approach that is useful in many scenarios: *functional construction*. Functional construction treats modifying data as a problem of transformation, rather than as detailed manipulation of a data store. If you can take a representation of data and transform it efficiently from one form to another, the result is the same as if you took one data store and manipulated it in some way to take another shape. A key to the functional construction approach is to pass the results of queries to and constructors. -In many cases you can write the transformational code in a fraction of the time that it would take to manipulate the data store, and the resulting code is more robust and easier to maintain. In these cases, even though the transformational approach can take more processing power, it is a more effective way to modify data. If a developer is familiar with the functional approach, the resulting code in many cases is easier to understand, and it is easy to find the code that modifies each part of the tree. +In many cases you can write the transformational code in a fraction of the time that it would take to manipulate the data store, and the resulting code is more robust and easier to maintain. In these cases, even though the transformational approach can take more processing power, it's a more effective way to modify data. If a developer is familiar with the functional approach, the resulting code in many cases is easier to understand, and it's easy to find the code that modifies each part of the tree. The approach where you modify an XML tree in place is more familiar to many DOM programmers, whereas code written using the functional approach might look unfamiliar to a developer who doesn't yet understand that approach. If you have to only make a small modification to a large XML tree, the approach where you modify a tree in place in many cases will take less CPU time. @@ -63,7 +63,7 @@ This example produces the following output: ## Example: Transform attributes into elements with the functional construction approach -By contrast, a functional approach consists of code to form a new tree, picking and choosing elements and attributes from the source tree, and transforming them as appropriate as they are added to the new tree. +By contrast, a functional approach consists of code to form a new tree, picking and choosing elements and attributes from the source tree, and transforming them as appropriate as they're added to the new tree. ```csharp XElement root = XElement.Load("Data.xml"); diff --git a/docs/csharp/programming-guide/concepts/linq/linq-to-xml-annotations.md b/docs/standard/linq/linq-xml-annotations.md similarity index 72% rename from docs/csharp/programming-guide/concepts/linq/linq-to-xml-annotations.md rename to docs/standard/linq/linq-xml-annotations.md index e44cf3a3c3011..0746739db217a 100644 --- a/docs/csharp/programming-guide/concepts/linq/linq-to-xml-annotations.md +++ b/docs/standard/linq/linq-xml-annotations.md @@ -1,15 +1,16 @@ --- -title: "LINQ to XML Annotations3" +title: LINQ to XML annotations - LINQ to XML +description: Learn how to add annotations to components of an XML tree. ms.date: 07/20/2015 ms.assetid: 54e7b9d0-07f5-488f-9065-b6e6b870f810 --- -# LINQ to XML Annotations +# LINQ to XML annotations (LINQ to XML) -Annotations in [!INCLUDE[sqltecxlinq](~/includes/sqltecxlinq-md.md)] enable you to associate any arbitrary object of any arbitrary type with any XML component in an XML tree. +Annotations in LINQ to XML enable you to associate any arbitrary object of any arbitrary type with any XML component in an XML tree. To add an annotation to an XML component, such as an or , you call the method. You retrieve annotations by type. -Note that annotations are not part of the XML infoset; they are not serialized or deserialized. +Note that annotations aren't part of the XML infoset; they're not serialized or deserialized. ## Methods diff --git a/docs/standard/linq/linq-xml-vs-dom.md b/docs/standard/linq/linq-xml-vs-dom.md index 34b869d0a2e9b..d8dc1a8703807 100644 --- a/docs/standard/linq/linq-xml-vs-dom.md +++ b/docs/standard/linq/linq-xml-vs-dom.md @@ -157,7 +157,7 @@ When using LINQ to XML, you use the class only ## Simplified handling of names and namespaces -Handling names, namespaces, and namespace prefixes is generally a complex part of XML programming. LINQ to XML simplifies names and namespaces by eliminating the requirement to deal with namespace prefixes. If you want to control namespace prefixes, you can. But if you decide to not explicitly control namespace prefixes, LINQ to XML will assign namespace prefixes during serialization if they're required, or will serialize using default namespaces if they aren't. If default namespaces are used, there will be no namespace prefixes in the resulting document. For more information, see [Namespaces overview](namespaces-overview.md). +Handling names, namespaces, and namespace prefixes is generally a complex part of XML programming. LINQ to XML simplifies names and namespaces by eliminating the requirement to deal with namespace prefixes. If you want to control namespace prefixes, you can. But if you decide to not explicitly control namespace prefixes, LINQ to XML will assign namespace prefixes during serialization if they're required, or will serialize using default namespaces if they're not. If default namespaces are used, there will be no namespace prefixes in the resulting document. For more information, see [Namespaces overview](namespaces-overview.md). Another problem with the DOM is that it doesn't let you change the name of a node. Instead, you have to create a new node and copy all the child nodes to it, losing the original node identity. LINQ to XML avoids this problem by enabling you to set the property on a node. diff --git a/docs/standard/linq/pre-atomization-xname-objects.md b/docs/standard/linq/pre-atomization-xname-objects.md new file mode 100644 index 0000000000000..15c588ea78381 --- /dev/null +++ b/docs/standard/linq/pre-atomization-xname-objects.md @@ -0,0 +1,169 @@ +--- +title: Pre-Atomization of XName objects - LINQ to XML +description: Learn how to pre-atomize to improve performance when you create a large number of elements with the same name. +ms.date: 07/20/2015 +dev_langs: + - "csharp" + - "vb" +ms.assetid: e84fbbe7-f072-4771-bfbb-059d18e1ad15 +--- + +# Pre-Atomization of XName objects (LINQ to XML) + +One way to improve performance in LINQ to XML is to pre-atomize objects. Pre-atomization means that you assign a string to an object before you create the XML tree by using the constructors of the and classes. Then, instead of passing a string to the constructor, which would use the implicit conversion from string to , you pass the initialized object. + +This improves performance when you create a large XML tree in which names are repeated. To do this, you declare and initialize objects before you construct the XML tree, and then use the objects instead of specifying strings for the element and attribute names. This technique can yield significant performance gains if you're creating a large number of elements or attributes with the same name. + +You should test pre-atomization with your scenario to decide if you should use it. + +## Example: Create elements in various ways, with and without pre-atomization + +The following example demonstrates pre-atomization. + +```csharp +XName Root = "Root"; +XName Data = "Data"; +XName ID = "ID"; + +XElement root = new XElement(Root, + new XElement(Data, + new XAttribute(ID, "1"), + "4,100,000"), + new XElement(Data, + new XAttribute(ID, "2"), + "3,700,000"), + new XElement(Data, + new XAttribute(ID, "3"), + "1,150,000") +); + +Console.WriteLine(root); +``` + +```vb +Dim root1 As XName = "Root" +Dim data As XName = "Data" +Dim id As XName = "ID" + +Dim root2 As New XElement(root1, New XElement(data, New XAttribute(id, "1"), "4,100,000"), + New XElement(data, New XAttribute(id, "2"), "3,700,000"), + New XElement(data, New XAttribute(id, "3"), "1,150,000")) + +Console.WriteLine(root2) +``` + +This example produces the following output: + +```xml + + 4,100,000 + 3,700,000 + 1,150,000 + +``` + +The following example shows the same technique for an XML document in a namespace: + +```csharp +XNamespace aw = "http://www.adventure-works.com"; +XName Root = aw + "Root"; +XName Data = aw + "Data"; +XName ID = "ID"; + +XElement root = new XElement(Root, + new XAttribute(XNamespace.Xmlns + "aw", aw), + new XElement(Data, + new XAttribute(ID, "1"), + "4,100,000"), + new XElement(Data, + new XAttribute(ID, "2"), + "3,700,000"), + new XElement(Data, + new XAttribute(ID, "3"), + "1,150,000") +); + +Console.WriteLine(root); +``` + +```vb +Dim aw As XNamespace = "http://www.adventure-works.com" +Dim root1 As XName = aw + "Root" +Dim data As XName = aw + "Data" +Dim id As XName = "ID" + +Dim root2 As New XElement(root1, New XAttribute(XNamespace.Xmlns + "aw", aw), + New XElement(data, New XAttribute(id, "1"), "4,100,000"), + New XElement(data, New XAttribute(id, "2"), "3,700,000"), + New XElement(data, New XAttribute(id, "3"), "1,150,000")) + +Console.WriteLine(root2) +``` + +This example produces the following output: + +```xml + + 4,100,000 + 3,700,000 + 1,150,000 + +``` + +The following example is more similar to what you will likely encounter in the real world. In this example, the content of the element is supplied by a query: + +```csharp +XName Root = "Root"; +XName Data = "Data"; +XName ID = "ID"; + +DateTime t1 = DateTime.Now; +XElement root = new XElement(Root, + from i in System.Linq.Enumerable.Range(1, 100000) + select new XElement(Data, + new XAttribute(ID, i), + i * 5) +); +DateTime t2 = DateTime.Now; + +Console.WriteLine("Time to construct:{0}", t2 - t1); +``` + +```vb +Dim root1 As XName = "Root" +Dim data As XName = "Data" +Dim id As XName = "ID" + +Dim sw As Stopwatch = Stopwatch.StartNew() +Dim root2 As New XElement(root1, From i In Enumerable.Range(1, 100000) + Select New XElement(data, New XAttribute(ID, i), i * 5)) +sw.Stop() +Console.WriteLine($"Time to construct: {sw.ElapsedMilliseconds} milliseconds") +``` + +The previous example performs better than the following example, in which names aren't pre-atomized: + +```csharp +DateTime t1 = DateTime.Now; +XElement root = new XElement("Root", + from i in System.Linq.Enumerable.Range(1, 100000) + select new XElement("Data", + new XAttribute("ID", i), + i * 5) +); +DateTime t2 = DateTime.Now; + +Console.WriteLine("Time to construct:{0}", t2 - t1); +``` + +```vb +Dim sw As Stopwatch = Stopwatch.StartNew() +Dim root As New XElement("Root", From i In Enumerable.Range(1, 100000) + Select New XElement("Data", New XAttribute("ID", i), i * 5)) +sw.Stop() +Console.WriteLine($"Time to construct: {sw.ElapsedMilliseconds} milliseconds") +``` + +## See also + +- [Atomized XName and XNamespace objects](atomized-xname-xnamespace-objects.md) diff --git a/docs/standard/linq/project-new-type.md b/docs/standard/linq/project-new-type.md index e17fac514b09f..0ede41b5a4983 100644 --- a/docs/standard/linq/project-new-type.md +++ b/docs/standard/linq/project-new-type.md @@ -10,7 +10,7 @@ ms.assetid: 48145cf9-1e0b-4e73-bbfd-28fc04800dc4 # How to project a new type (LINQ to XML) -Other examples in this section have shown queries that return results as of , of `string`, and of `int`. These are common result types, but they aren't appropriate for every scenario. In many cases, you'll want your queries to return an of some other type. +Other examples in this section have shown queries that return results as of , of `string`, and of `int`. These are common result types, but they're not appropriate for every scenario. In many cases, you'll want your queries to return an of some other type. ## Example: Define a new type and have the `select` statement create an instance of the type diff --git a/docs/standard/linq/statically-compiled-queries.md b/docs/standard/linq/statically-compiled-queries.md new file mode 100644 index 0000000000000..03523017210fc --- /dev/null +++ b/docs/standard/linq/statically-compiled-queries.md @@ -0,0 +1,128 @@ +--- +title: Statically compiled queries - LINQ to XML +description: +ms.date: 07/20/2015 +dev_langs: + - "csharp" + - "vb" +ms.assetid: 3bf558fe-0705-479d-86d4-00188f5fcf9c +--- +# Statically compiled queries (LINQ to XML) + +One of the most important performance advantages of LINQ to XML, as compared to , is that queries in LINQ to XML are statically compiled, whereas XPath queries must be interpreted at run time. This feature is built into LINQ to XML, so you don't have to perform extra steps to take advantage of it, but it's helpful to understand the distinction when choosing between the two technologies. This topic explains the difference. + +## Statically compiled queries vs. XPath + +The following example shows how to get the descendant elements with a specified name, and with an attribute with a specified value. The equivalent XPath expression is `//Address[@Type='Shipping']`. + +```csharp +XDocument po = XDocument.Load("PurchaseOrders.xml"); + +IEnumerable list1 = + from el in po.Descendants("Address") + where (string)el.Attribute("Type") == "Shipping" + select el; + +foreach (XElement el in list1) + Console.WriteLine(el); +``` + +```vb +Dim po = XDocument.Load("PurchaseOrders.xml") + +Dim list1 = From el In po.Descendants("Address") + Where el.@Type = "Shipping" + +For Each el In list1 + Console.WriteLine(el) +Next +``` + +The query expression in this example is rewritten by the compiler to method-based query syntax. The following example, which is written in method-based query syntax, produces the same results as the previous one: + +```csharp +XDocument po = XDocument.Load("PurchaseOrders.xml"); + +IEnumerable list1 = + po + .Descendants("Address") + .Where(el => (string)el.Attribute("Type") == "Shipping"); + +foreach (XElement el in list1) + Console.WriteLine(el); +``` + + ```vb +Dim po = XDocument.Load("PurchaseOrders.xml") + +Dim list1 As IEnumerable(Of XElement) = po.Descendants("Address").Where(Function(el) el.@Type = "Shipping") + +For Each el In list1 + Console.WriteLine(el) +Next +``` + +The method is an extension method. For more information, see [Extension Methods (C# Programming Guide)](../../csharp/programming-guide/classes-and-structs/extension-methods.md). Because is an extension method, the query above is compiled as though it were written as follows: + +```csharp +XDocument po = XDocument.Load("PurchaseOrders.xml"); + +IEnumerable list1 = + System.Linq.Enumerable.Where( + po.Descendants("Address"), + el => (string)el.Attribute("Type") == "Shipping"); + +foreach (XElement el in list1) + Console.WriteLine(el); +``` + +```vb +Dim po = XDocument.Load("PurchaseOrders.xml") + +Dim list1 = Enumerable.Where(po.Descendants("Address"), Function(el) el.@Type = "Shipping") + +For Each el In list1 + Console.WriteLine(el) +Next +``` + +This example produces exactly the same results as the previous two examples. This illustrates the fact that queries are effectively compiled into statically linked method calls. This, combined with the deferred execution semantics of iterators, improves performance. For more information about the deferred execution semantics of iterators, see [Deferred execution and lazy evaluation](deferred-execution-lazy-evaluation.md). + +> [!NOTE] +> These examples are representative of the code that the compiler might write. The actual implementation might differ slightly from these examples, but the performance will be the same as, or similar to, these examples. + +## Executing XPath expressions with XmlDocument + +The following example uses to accomplish the same results as the previous examples: + +```csharp +XmlReader reader = XmlReader.Create("PurchaseOrders.xml"); +XmlDocument doc = new XmlDocument(); +doc.Load(reader); +XmlNodeList nl = doc.SelectNodes(".//Address[@Type='Shipping']"); +foreach (XmlNode n in nl) + Console.WriteLine(n.OuterXml); +reader.Close(); +``` + +```vb +Dim reader = Xml.XmlReader.Create("PurchaseOrders.xml") +Dim doc As New Xml.XmlDocument() +doc.Load(reader) +Dim nl As Xml.XmlNodeList = doc.SelectNodes(".//Address[@Type='Shipping']") +For Each n As Xml.XmlNode In nl + Console.WriteLine(n.OuterXml) +Next +reader.Close() +``` + +This query returns the same output as the examples that use LINQ to XML; the only difference is that LINQ to XML indents the printed XML, whereas doesn't. + +However, the approach generally doesn't perform as well as LINQ to XML, because the method must do the following every time it's called: + +- Parse the string that contains the XPath expression, breaking the string into tokens. +- Validate the tokens to make sure that the XPath expression is valid. +- Translate the expression into an internal expression tree. +- Iterate through the nodes, appropriately selecting the nodes for the result set based on the evaluation of the expression. + +This is significantly more than the work done by the corresponding LINQ to XML query. The specific performance difference varies for different types of queries, but in general LINQ to XML queries do less work, and therefore perform better, than evaluating XPath expressions using . diff --git a/docs/standard/linq/wordprocessingml-document-styles.md b/docs/standard/linq/wordprocessingml-document-styles.md index a822066de31d7..e9d8e8b122115 100644 --- a/docs/standard/linq/wordprocessingml-document-styles.md +++ b/docs/standard/linq/wordprocessingml-document-styles.md @@ -12,7 +12,7 @@ ms.assetid: 40e35de6-ac93-4bba-88ab-a018cbe93873 This article presents a WordprocessingML document that is more complicated than the one in [The XML shape of WordprocessingML documents](xml-shape-wordprocessingml-documents.md); specifically, it presents a document whose paragraphs are formatted with styles. -To understand styles it is helpful to know something about document structure. A WordprocessingML document is stored in a *package* that comprises *parts*. Specifically, the term *package* corresponds to a ZIP archive and the term *part* corresponds to a file stored within the ZIP. If a document contains paragraphs that are formatted with styles, there will be a document part that contains paragraphs that have styles applied to them, and a style part that defines the styles referenced in the document part. +To understand styles, it's helpful to know something about document structure. A WordprocessingML document is stored in a *package* that comprises *parts*. Specifically, the term *package* corresponds to a ZIP archive and the term *part* corresponds to a file stored within the ZIP. If a document contains paragraphs that are formatted with styles, there will be a document part that contains paragraphs that have styles applied to them, and a style part that defines the styles referenced in the document part. The easiest way to see the XML that makes up an Office Open XML document is to run the example in [Example that outputs Office Open XML document parts](example-outputs-office-open-xml-document-parts.md). diff --git a/docs/standard/linq/xml-shape-wordprocessingml-documents.md b/docs/standard/linq/xml-shape-wordprocessingml-documents.md index 8523a6d639a3b..f49879b867162 100644 --- a/docs/standard/linq/xml-shape-wordprocessingml-documents.md +++ b/docs/standard/linq/xml-shape-wordprocessingml-documents.md @@ -14,7 +14,7 @@ This article introduces the XML shape of a WordprocessingML document. ## Microsoft Office formats -The native file format for the 2007 Microsoft Office system is Office Open XML (commonly called Open XML). Open XML is an XML-based format that is an Ecma standard and is currently going through the ISO-IEC standards process. The markup language for word processing files within Open XML is called WordprocessingML. This tutorial uses WordprocessingML source files as input for the examples. +The native file format for the 2007 Microsoft Office system is Office Open XML (commonly called Open XML). Open XML is an XML-based format that's an Ecma standard and is currently going through the ISO-IEC standards process. The markup language for word processing files within Open XML is called WordprocessingML. This tutorial uses WordprocessingML source files as input for the examples. If you're using Microsoft Office 2003, you can save documents in the Office Open XML format if you have installed the Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint 2007 File Formats. diff --git a/docs/visual-basic/programming-guide/concepts/linq/linq-to-xml-annotations.md b/docs/visual-basic/programming-guide/concepts/linq/linq-to-xml-annotations.md deleted file mode 100644 index 8c7fd2f42d8df..0000000000000 --- a/docs/visual-basic/programming-guide/concepts/linq/linq-to-xml-annotations.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "LINQ to XML Annotations2" -ms.date: 07/20/2015 -ms.assetid: c3e8b3ff-fceb-4428-b0ca-1ed6f128aac8 ---- -# LINQ to XML Annotations -Annotations in [!INCLUDE[sqltecxlinq](~/includes/sqltecxlinq-md.md)] enable you to associate any arbitrary object of any arbitrary type with any XML component in an XML tree. - - To add an annotation to an XML component, such as an or , you call the method. You retrieve annotations by type. - - Note that annotations are not part of the XML infoset; they are not serialized or deserialized. - -## Methods - You can use the following methods when working with annotations: - -|Method|Description| -|------------|-----------------| -||Adds an object to the annotation list of an .| -||Gets the first annotation object of the specified type from an .| -||Gets a collection of annotations of the specified type for an .| -||Removes the annotations of the specified type from an .| - -## See also - -- [Advanced LINQ to XML Programming (Visual Basic)](advanced-linq-to-xml-programming.md) diff --git a/docs/visual-basic/programming-guide/concepts/linq/pre-atomization-of-xname-objects-linq-to-xml.md b/docs/visual-basic/programming-guide/concepts/linq/pre-atomization-of-xname-objects-linq-to-xml.md deleted file mode 100644 index c034c54387a82..0000000000000 --- a/docs/visual-basic/programming-guide/concepts/linq/pre-atomization-of-xname-objects-linq-to-xml.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "Pre-Atomization of XName Objects (LINQ to XML)" -ms.date: 07/20/2015 -ms.assetid: 06ea104b-f44c-4bb2-9c34-889ae025c80d ---- -# Pre-Atomization of XName Objects (LINQ to XML) (Visual Basic) - -One way to improve performance in LINQ to XML is to pre-atomize objects. Pre-atomization means that you assign a string to an object before you create the XML tree by using the constructors of the and classes. Then, instead of passing a string to the constructor, which would use the implicit conversion from string to , you pass the initialized object. - -This improves performance when you create a large XML tree in which specific names are repeated. To do this, you declare and initialize objects before you construct the XML tree, and then use the objects instead of specifying strings for the element and attribute names. This technique can yield significant performance gains if you are creating a large number of elements (or attributes) with the same name. - -You should test pre-atomization with your scenario to decide if you should use it. - -## Example - -The following example demonstrates this: - -```vb -Dim root1 As XName = "Root" -Dim data As XName = "Data" -Dim id As XName = "ID" - -Dim root2 As New XElement(root1, New XElement(data, New XAttribute(id, "1"), "4,100,000"), - New XElement(data, New XAttribute(id, "2"), "3,700,000"), - New XElement(data, New XAttribute(id, "3"), "1,150,000")) - -Console.WriteLine(root2) -``` - -This example produces the following output: - -```xml - - 4,100,000 - 3,700,000 - 1,150,000 - -``` - -The following example shows the same technique where the XML document is in a namespace: - -```vb -Dim aw As XNamespace = "http://www.adventure-works.com" -Dim root1 As XName = aw + "Root" -Dim data As XName = aw + "Data" -Dim id As XName = "ID" - -Dim root2 As New XElement(root1, New XAttribute(XNamespace.Xmlns + "aw", aw), - New XElement(data, New XAttribute(id, "1"), "4,100,000"), - New XElement(data, New XAttribute(id, "2"), "3,700,000"), - New XElement(data, New XAttribute(id, "3"), "1,150,000")) - -Console.WriteLine(root2) -``` - -This example produces the following output: - -```xml - - 4,100,000 - 3,700,000 - 1,150,000 - -``` - -The following example is more similar to what you will likely encounter in the real world. In this example, the content of the element is supplied by a query: - -```vb -Dim root1 As XName = "Root" -Dim data As XName = "Data" -Dim id As XName = "ID" - -Dim sw As Stopwatch = Stopwatch.StartNew() -Dim root2 As New XElement(root1, From i In Enumerable.Range(1, 100000) - Select New XElement(data, New XAttribute(ID, i), i * 5)) -sw.Stop() -Console.WriteLine($"Time to construct: {sw.ElapsedMilliseconds} milliseconds") -``` - -The previous example performs better than the following example, in which names are not pre-atomized: - -```vb -Dim sw As Stopwatch = Stopwatch.StartNew() -Dim root As New XElement("Root", From i In Enumerable.Range(1, 100000) - Select New XElement("Data", New XAttribute("ID", i), i * 5)) -sw.Stop() -Console.WriteLine($"Time to construct: {sw.ElapsedMilliseconds} milliseconds") -``` - -## See also - -- [Performance (LINQ to XML) (Visual Basic)](performance-linq-to-xml.md) -- [Atomized XName and XNamespace Objects (LINQ to XML) (Visual Basic)](atomized-xname-and-xnamespace-objects-linq-to-xml.md) diff --git a/docs/visual-basic/programming-guide/concepts/linq/statically-compiled-queries-linq-to-xml.md b/docs/visual-basic/programming-guide/concepts/linq/statically-compiled-queries-linq-to-xml.md deleted file mode 100644 index a1b763a7883c5..0000000000000 --- a/docs/visual-basic/programming-guide/concepts/linq/statically-compiled-queries-linq-to-xml.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "Statically Compiled Queries (LINQ to XML)" -ms.date: 07/20/2015 -ms.assetid: 3f4825c7-c3b0-48da-ba4e-8e97fb2a2f34 ---- -# Statically Compiled Queries (LINQ to XML) (Visual Basic) - -One of the most important performance benefits LINQ to XML, as opposed to , is that queries in LINQ to XML are statically compiled, whereas XPath queries must be interpreted at run time. This feature is built in to LINQ to XML, so you do not have to perform extra steps to take advantage of it, but it is helpful to understand the distinction when choosing between the two technologies. This topic explains the difference. - -## Statically Compiled Queries vs. XPath - -The following example shows how to get the descendant elements with a specified name, and with an attribute with a specified value. - -The following is the equivalent XPath expression: - -```vb -//Address[@Type='Shipping'] -``` - -```vb -Dim po = XDocument.Load("PurchaseOrders.xml") - -Dim list1 = From el In po.Descendants("Address") - Where el.@Type = "Shipping" - -For Each el In list1 - Console.WriteLine(el) -Next -``` - -The query expression in this example is re-written by the compiler to method-based query syntax. The following example, which is written in method-based query syntax, produces the same results as the previous one: - -```vb -Dim po = XDocument.Load("PurchaseOrders.xml") - -Dim list1 As IEnumerable(Of XElement) = po.Descendants("Address").Where(Function(el) el.@Type = "Shipping") - -For Each el In list1 - Console.WriteLine(el) -Next -``` - -The method is an extension method. For more information, see [Extension Methods](../../../../csharp/programming-guide/classes-and-structs/extension-methods.md). Because is an extension method, the query above is compiled as though it were written as follows: - -```vb -Dim po = XDocument.Load("PurchaseOrders.xml") - -Dim list1 = Enumerable.Where(po.Descendants("Address"), Function(el) el.@Type = "Shipping") - -For Each el In list1 - Console.WriteLine(el) -Next -``` - -This example produces exactly the same results as the previous two examples. This illustrates the fact that queries are effectively compiled into statically linked method calls. This, combined with the deferred execution semantics of iterators, improves performance. For more information about the deferred execution semantics of iterators, see [Deferred Execution and Lazy Evaluation in LINQ to XML (Visual Basic)](deferred-execution-and-lazy-evaluation-in-linq-to-xml.md). - -> [!NOTE] -> These examples are representative of the code that the compiler might write. The actual implementation might differ slightly from these examples, but the performance will be the same or similar to these examples. - -## Executing XPath Expressions with XmlDocument - -The following example uses to accomplish the same results as the previous examples: - -```vb -Dim reader = Xml.XmlReader.Create("PurchaseOrders.xml") -Dim doc As New Xml.XmlDocument() -doc.Load(reader) -Dim nl As Xml.XmlNodeList = doc.SelectNodes(".//Address[@Type='Shipping']") -For Each n As Xml.XmlNode In nl - Console.WriteLine(n.OuterXml) -Next -reader.Close() -``` - -This query returns the same output as the examples that use LINQ to XML; the only difference is that LINQ to XML indents the printed XML, whereas does not. - -However, the approach generally does not perform as well as LINQ to XML, because the method must do the following internally every time it is called: - -- It parses the string that contains the XPath expression, breaking the string into tokens. - -- It validates the tokens to make sure that the XPath expression is valid. - -- It translates the expression into an internal expression tree. - -- It iterates through the nodes, appropriately selecting the nodes for the result set based on the evaluation of the expression. - -This is significantly more than the work done by the corresponding LINQ to XML query. The specific performance difference varies for different types of queries, but in general LINQ to XML queries do less work, and therefore perform better, than evaluating XPath expressions using . - -## See also - -- [Performance (LINQ to XML) (Visual Basic)](performance-linq-to-xml.md)