Programming Taskbook


E-mail:

Password:

User registration   Restore password

Russian

SFedU SMBU

Electronic problem book on programming

©  M. E. Abramyan (Southern Federal University, Shenzhen MSU-BIT University), 1998–2026

 

PT for LINQ | Task groups | LinqXml

PrevNext


Using LINQ to XML

Node of an XML document refers to any of its components that is not an attribute, in particular, a comment, processing instruction, or plain text. An element of an XML document is a named component that can contain other nodes and can also have attributes. In the X-DOM object model, which is part of the LINQ to XML interface, each type of XML document component is associated with a corresponding class: XObject — the common ancestor of all components, XNode — the common ancestor of all nodes, XText — a text node, i.e., a node representing plain text, XComment — a comment, XProcessingInstruction — a processing instruction, XElement — an element, XAttribute — an attribute. The XML document is associated with the XDocument class.

If a certain node B of an XML document is contained within a certain element A, then element A is called an ancestor of node B, and node B is a descendant of element A. If element A is the closest ancestor of node B, then B is called a child node of element A, and element A is the parent of node B; if node B is an element, then it is called a child element of element A. The first element of an XML document is called the root element; the root element is an ancestor of all other elements in the XML document, while the root element itself has no ancestors.

The root element is considered a level 0 element, its child nodes/elements are level 1 nodes/elements, their child nodes/elements are level 2 nodes/elements, and so on. An XML document has a single level 0 element (the root element), however there can be multiple level 0 nodes (comments or processing instructions).

If a task states that an element contains a text string (or a number), this means that the corresponding string (or the string representation of the number) is a child text node of this element.

In all problems, it is assumed that an element has no more than one child text node, and the text node contains at least one significant character (i.e., a character that is not a space or a control character). When saving an XML document, use the Save method of the XDocument class with a single parameter — the filename; this will ensure automatic formatting of the saved document and removal of all text nodes that do not contain significant characters.

Elements that contain no child nodes can be represented in two forms: as paired tags with no text between them (<a></a>), or as a single combined tag (<a />). Elements that contain no nodes can have attributes.

If a task states that an XML document is given, this means that the name of the file containing this document is given. Transforming an XML document must always end with saving the transformed document to the same file from which the original version of this document was read.

If a task mentions the ordinal numbers of elements in a sequence, it is assumed that numbering starts from 1.

In the task of subgroups preceding the subgroup "Working with XML Document Namespaces", it is assumed that all element and attribute names of the XML document have an empty namespace.

Notes provided for certain tasks should also be considered when performing subsequent tasks in the current subgroup.

Creating XML Documents

In all tasks of this subgroup, it is assumed that the initial text files contain text in the single-byte ASCII encoding, and all file lines are non-empty. The created XML documents must have the "us-ascii" encoding.

LinqXml1°. Given the names of an existing text file and an XML document to be created. Create an XML document with a root element root and first-level elements line, each containing one line from the source file.

Note. In the constructor of the root element, use a sequence of XElement objects obtained by the Select method from the original sequence of lines.

LinqXml2°. Given the names of an existing text file and an XML document to be created. Create an XML document with a root element root and first-level elements, each containing one line from the source file and having a name line with the line's ordinal number appended to it (line1, line2, etc.).

LinqXml3°. Given the names of an existing text file and an XML document to be created. Create an XML document with a root element root and first-level elements line, each containing one line from the source file. The element containing the line with ordinal number N (1, 2, …) must have an attribute num with a value equal to N.

LinqXml4°. Given the names of an existing text file and an XML document to be created. Each line of the text file contains several (one or more) words separated by exactly one space. Create an XML document with a root element root, first-level elements line, and second-level elements word. The line elements correspond to the lines of the source file and contain no child text nodes; the word elements of each line element contain one word from the corresponding line (words are arranged in alphabetical order).

LinqXml5°. Given the names of an existing text file and an XML document to be created. Each line of the text file contains several (one or more) words separated by exactly one space. Create an XML document with a root element root, first-level elements line, and second-level elements word. The line elements correspond to the lines of the source file and contain no child text nodes; the word elements of each line element contain one word from the corresponding line (words are arranged in the order they appear in the source line). The line element must have an attribute num equal to the ordinal number of the line in the source file, and the word element must have an attribute num equal to the ordinal number of the word in the line.

LinqXml6°. Given the names of an existing text file and an XML document to be created. Each line of the text file contains several (one or more) integers separated by exactly one space. Create an XML document with a root element root, first-level elements line, and second-level elements number. The line elements correspond to the lines of the source file and contain no child text nodes; the number elements of each line element contain one number from the corresponding line (numbers are arranged in descending order). The line element must have an attribute sum equal to the sum of all numbers from the corresponding line.

LinqXml7°. Given the names of an existing text file and an XML document to be created. Each line of the text file contains several (one or more) integers separated by exactly one space. Create an XML document with a root element root, first-level elements line, and second-level elements sum-positive and number-negative. The line elements correspond to the lines of the source file and contain no child text nodes; the sum-positive element is the first child element of each line element and contains the sum of all positive numbers from the corresponding line; the number-negative elements contain one negative number each from the corresponding line (numbers are arranged in the reverse order of their appearance in the source line).

LinqXml8°. Given the names of an existing text file and an XML document to be created. Each line of the text file contains several (one or more) words separated by exactly one space. Create an XML document with a root element root, first-level elements line, second-level elements word, and third-level elements char. The line and word elements contain no child text nodes. The line elements correspond to the lines of the source file; the word elements of each line element correspond to the words from that line (words are arranged in alphabetical order); the char elements of each word element contain one character each from the corresponding word (characters are arranged in the order they appear in the word).

LinqXml9°. Given the names of an existing text file and an XML document to be created. Create an XML document with a root element root, first-level elements line, and comments (comments are child nodes of the root element). If a line of the text file starts with the text "comment:", then it (without the text "comment:") is added to the XML document as the next comment; otherwise, the line is added as a child text node to the next line element.

LinqXml10°. Given the names of an existing text file and an XML document to be created. Create an XML document with a root element root, first-level elements line, and processing instructions (processing instructions are child nodes of the root element). If a line of the text file starts with the text "data:", then it (without the text "data:") is added to the XML document as the data for the next processing instruction named instr; otherwise, the line is added as a child text node to the next line element.

Analyzing XML Documents

LinqXml11°. Given an XML document. Find all distinct names of its elements and output each found name along with the number of its occurrences in the document. Output element names in the order of their first occurrence.

Note. Use the GroupBy method.

LinqXml12°. Given an XML document containing at least one first-level element. Find all distinct names of first-level elements and output each found name along with the number of its occurrences in the document as a first-level element name. Output element names in alphabetical order.

LinqXml13°. Given an XML document containing at least one attribute. Output all distinct names of attributes present in the document. The order of attribute names must correspond to the order of their first occurrence in the document.

Note. Use the SelectMany and Distinct methods.

LinqXml14°. Given an XML document. Find second-level elements that have a child text node, and output the count of found elements, as well as the name of each found element and the value of its child text node. The output order of elements must correspond to their order in the document.

LinqXml15°. Given an XML document containing at least one first-level element. For each first-level element, find the number of its descendants that have at least two attributes, and output the name of the first-level element and the found count of its descendants. Output elements in alphabetical order of their names, and if names coincide — in ascending order of the found descendant count.

LinqXml16°. Given an XML document containing at least one first-level element. For each first-level element, find the total number of attributes of its second-level descendant elements (i.e., elements that are child elements of its child elements) and output the found number of attributes and the element's name. Output elements in descending order of the found attribute count, and if attribute counts coincide — in alphabetical order of names.

LinqXml17°. Given an XML document containing at least one text node. Find all distinct names of elements that have a child text node, and output these names, as well as the values of all child text nodes associated with them. Output names in alphabetical order; text values associated with each name should be output in the order of their appearance in the document.

LinqXml18°. Given an XML document containing at least one attribute. Find all distinct names of attributes and output these names, as well as all associated values (all values are considered textual). The order of names must correspond to the order of their first occurrence in the document; values associated with each name should be output in alphabetical order.

LinqXml19°. Given an XML document containing at least one first-level element. For each first-level element, find its child elements that have the maximum number of descendants (when counting the number of descendants, also consider descendant nodes that are not elements). Iterating through first-level elements in the order of their appearance in the XML document, output the element's name, the number N — the maximum number of descendants among its child elements (the value N can be 0) — and the names of all child elements that have N descendants (output child element names in alphabetical order; among these names there may be duplicates). If a first-level element has no child elements, then output −1 as the value N, and "no child" as the child element name.

LinqXml20°. Given an XML document containing at least one first-level element. For each first-level element, find its descendant elements that have the maximum number of attributes. Iterating through first-level elements in the order of their appearance in the XML document, output the element's name, the number N — the maximum number of attributes among its descendants (the value N can be 0) — and the names of descendants that have N attributes (output descendant names in alphabetical order; among these names there may be duplicates). If a first-level element has no descendant elements, then output −1 as the value N, and "no child" as the descendant name.

Transforming XML Documents

LinqXml21°. Given an XML document and a string S. The string contains the name of one of the non-root elements of the source document. Remove from the document all first-level elements with the name S.

Note. Apply the Remove method to the sequence Elements(S) of the root element.

LinqXml22°. Given an XML document and a string S. The string contains the name of one of the non-root elements of the source document. Remove from the document all elements with the name S.

LinqXml23°. Given an XML document. Remove all processing instructions from the document.

Note. To get the sequence of all processing instructions, use the method OfType<XProcessingInstruction>.

LinqXml24°. Given an XML document. Remove from the document all comments that are first or second-level nodes (i.e., those whose parent element is the root element or a first-level element).

LinqXml25°. Given an XML document. For all first and second-level elements that have more than one attribute, remove all their attributes.

LinqXml26°. Given an XML document. For all elements of the document, remove all their attributes except the first one.

Note. In the predicate of the Where method that selects all attributes of an element except the first, use the PreviousAttribute method of the XAttribute class.

LinqXml27°. Given an XML document. For all second-level elements, remove all their child nodes except the last one.

LinqXml28°. Given an XML document. Remove child text nodes for all third-level elements. If a text node is the only child node of an element, then after its removal the element should be represented as a combined tag.

Note. Use the OfType<XText> method.

LinqXml29°. Given an XML document. Remove from the document all first and second-level elements that contain no child nodes.

LinqXml30°. Given an XML document. Remove from the document all third-level elements represented as combined tags.

Note. Use the IsEmpty property of the XElement class.

LinqXml31°. Given an XML document and strings S1 and S2. The string S1 contains the name of one of the elements of the source document, the string S2 contains a valid XML element name. After each first-level element with the name S1, add an element with the name S2. The attributes and descendants of the added element must match the attributes and descendants of the preceding element.

Note. For each element S1, call the AddAfterSelf method with three parameters: the string S2 and the sequences Attributes and Nodes of the element S1.

LinqXml32°. Given an XML document and strings S1 and S2. The string S1 contains the name of one of the elements of the source document, the string S2 contains a valid XML element name. Before each second-level element with the name S1, add an element with the name S2. The added element must contain the last attribute and the first child element of the subsequent element (if they exist). If the element S1 has no child elements, then the element S2 added before it must be represented as a combined tag.

Note. Use the FirstOrDefault method.

LinqXml33°. Given an XML document. For each first-level element that has attributes, add to the end of its child nodes an element named attr with attributes matching the attributes of the processed first-level element, then remove all attributes from the processed element. The added attr element must be represented as a combined tag.

Note. Use the ReplaceAttributes method, specifying the new child element as the parameter.

LinqXml34°. Given an XML document. For each first-level element that has attributes, add to the end of its child nodes elements with names matching the names of its attributes and text values matching the values of the corresponding attributes, then remove all attributes of the processed first-level element.

Note. Use the ReplaceAttributes method, specifying as the parameter a sequence of elements obtained by the Select method from the sequence of attributes.

LinqXml35°. Given an XML document. For each second-level element, add to the end of its attribute list an attribute child-count with a value equal to the number of all child nodes of this element. If the element has no child nodes, then the child-count attribute must have the value 0.

LinqXml36°. Given an XML document. For each second-level element that has descendants, add to the end of its attribute list an attribute node-count with a value equal to the number of descendant nodes (of all levels) of this element.

LinqXml37°. Given an XML document. For each second-level element that has descendants, append to its text content the text content of all descendant elements, then remove all its descendant nodes except the child text node.

Note. Use the Value property of the XElement class.

LinqXml38°. Given an XML document. For each element except the root, change its name by adding to the left the original names of all its ancestors, separated by the "-" character (hyphen). For example, if the root element has the name root, then a second-level element bb whose parent element has the name aa should get the name root-aa-bb.

Note. Iterating through all elements of the Descendants sequence of the root element, use their Parent and Name properties.

LinqXml39°. Given an XML document. For each element except the root, change its name by adding to the left the original name of its parent element, supplemented by the "-" character (hyphen). For example, a third-level element cc whose parent element has the name bb should get the name bb-cc.

Note. Organize iteration of the Descendants sequence of the root element in reverse order (using the Reverse method).

LinqXml40°. Given an XML document. Change the names of attributes of all elements by adding to the left the name of the containing element, supplemented by the "-" character (hyphen).

Note. Since the Name property of the XAttribute class is read-only, form a new sequence of attributes with the required names and values (applying the Select method to the Attributes sequence), then specify it as a parameter of the ReplaceAttributes method.

Type Conversion When Processing XML Documents

LinqXml41°. Given an XML document. Any of its elements contains either a set of child elements or a textual representation of a real number. Add to each element containing child elements an attribute sum equal to the sum of the numbers specified in the child elements. The sum is rounded to two decimal places, insignificant zeros are not displayed. If none of the child elements contains a textual representation of a number, then the sum attribute should have the value 0.

Note. To convert the textual representation of a real number to the number itself, it is sufficient to cast the XML element containing this textual representation to the type double. To specify the numeric value of the sum attribute, it is sufficient to pass a real number, rounded in the required manner (using the Math.Round function with two parameters), as the second parameter of the XAttribute constructor.

LinqXml42°. Given an XML document in which the values of all attributes are textual representations of real numbers. Add to each first-level element containing child elements a child element sum containing the textual representation of the sum of the attributes of all child elements of this element. The sum is rounded to two decimal places, insignificant zeros are not displayed. If none of the child elements contains attributes, then the sum element should have the value 0.

LinqXml43°. Given an XML document in which the values of all attributes are textual representations of real numbers. Add to each first-level element containing child elements a child element max containing the textual representation of the maximum of the attribute values of all descendant elements of this element. If none of the descendant elements contains attributes, then do not add the max element.

Note. For uniform processing of two situations (presence or absence of attributes in descendants), one can build a sequence of numeric values of the Nullable type double? from the sequence of attributes, apply the Max method to it, and add a new max element using the SetElementValue method, specifying the result returned by the Max method as the second parameter. If there are no attributes in descendants, the Max method will return null; in this case, the SetElementValue method will not create a new element.

LinqXml44°. Given an XML document and a string S. The string contains the name of one of the attributes of the source document; it is known that all attributes with the specified name contain a textual representation of a real number. For each element, perform the following actions: iterating through all its descendants containing the attribute S, find the minimum value of this attribute and write this value into a new attribute min of the processed element. If none of the element's descendants contains the attribute S, then do not add the min attribute to this element.

Note. Use casting of the attribute Attribute(S) to the Nullable type double?; if the attribute with the specified name is absent, null will be returned. To create a new attribute with the found minimum value, use the SetAttributeValue method; in case of a null value, the attribute will not be created.

LinqXml45°. Given an XML document. For each element that has attributes, add to the beginning of its set of child nodes an element named odd-attr-count with a boolean value equal to true if the total number of attributes of this element and all its descendant elements is odd, and false otherwise.

Note. As a parameter of the XElement constructor that defines the element's value, a boolean expression should be used; this will display the value of the boolean constant in accordance with the XML standard.

LinqXml46°. Given an XML document. For each element that has child elements, add to the end of its set of attributes an attribute named odd-node-count with a boolean value equal to true if the total number of child nodes of all its child elements is odd, and false otherwise.

LinqXml47°. Given an XML document. For each element that has at least one child element, add a child element named has-comments with a boolean value equal to true if this element contains one or more comments among its descendant nodes, and false otherwise. Add the new element after the first existing child element.

LinqXml48°. Given an XML document. For each element that has at least two child nodes, add a child element named has-instructions with a boolean value equal to true if this element contains one or more processing instructions among its child nodes, and false otherwise. Add the new element before the last existing child node.

LinqXml49°. Given an XML document and a string S. The string contains the name of one of the attributes of the source document; it is known that all attributes with the specified name contain a representation of a time interval (in days, hours, minutes, and seconds) in the format adopted in the XML standard. Add to the root element an attribute total-time equal to the total value of the time intervals specified in all attributes S of the source document.

Note. Use casting of the XAttribute object to the type TimeSpan. To sum the obtained time intervals, use the Aggregate method and the "+" operation for the TimeSpan type.

LinqXml50°. Given an XML document. A certain time interval (in days, hours, minutes, and seconds) is associated with each element of the document. This interval is either explicitly specified in the time attribute of this element (in the format adopted in the XML standard), or, if this attribute is absent, is considered equal to one day. Add to the beginning of the set of child nodes of the root element an element total-time with a value equal to the total value of the time intervals associated with all first-level elements.

Note. Use casting of the XAttribute object to the Nullable type TimeSpan? and the ?? operation of C# (the binary If operation of VB.NET).

LinqXml51°. Given an XML document. Any of its elements contains either a set of child elements or a textual representation of some date, corresponding to the XML standard. Change all elements containing a date as follows: add an attribute year containing the year value from the original date, and a child element day with a textual value equal to the day value from the original date, then remove the original date from the processed element.

Note. Use casting of the XML element to the type DateTime.

LinqXml52°. Given an XML document. A certain date, determined by year, month, and day numbers, is associated with each element of the document. The components of this date are specified in the attributes year, month, day. If some of these attributes are absent, then the corresponding components are determined by default: 2000 for the year, 1 for the month, and 10 for the day. For each element, add to the beginning of its set of child nodes an element date with the textual representation of the date associated with the processed element (the date is written in the format adopted in the XML standard), and remove the existing attributes associated with the date components.

Working with XML Document Namespaces

LinqXml53°. Given an XML document. In each first-level element, a namespace is defined that applies to all its descendant elements. For each first-level element, add to the end of its set of child nodes an element named namespace with a value equal to the namespace of the processed first-level element (the namespace of the added element must match the namespace of its parent element).

LinqXml54°. Given an XML document whose root element and possibly some other elements have a non-empty namespace. Associate with the namespace of the root element all first and second-level elements; for elements of higher levels, leave their previous namespaces.

LinqXml55°. Given an XML document. Transform the names of all second-level elements by removing namespaces from them (for elements of other levels, do not change namespaces).

LinqXml56°. Given an XML document. A single namespace prefix is defined in the root element of the document. Provide all first-level element names with this prefix and remove the definitions of original namespaces from these elements (if such definitions exist).

LinqXml57°. Given an XML document and strings S1 and S2 containing different namespaces. Remove the definitions of the original namespaces in the document and define two namespace prefixes in the root element: prefix x associated with S1, and prefix y associated with S2. Provide elements of level zero and one with the prefix x, and elements of subsequent levels with the prefix y.

LinqXml58°. Given an XML document and a string S containing a certain namespace. Define in the root element a prefix node associated with the namespace specified in the string S, and add to each first-level element two attributes: an attribute node:count with a value equal to the number of descendant nodes for this element, and an attribute xml:count with a value equal to the number of descendant elements for this element (xml is the prefix of the XML namespace).

Note. Use the Xml property of the XNamespace class.

LinqXml59°. Given an XML document. In each of the first-level elements, a single namespace prefix is defined, and it is known that all attributes with this prefix have integer values. For each first-level element and its descendant elements, double the values of all attributes with the namespace prefix defined in this element.

LinqXml60°. Given an XML document whose root element contains definitions of two namespace prefixes named x and y. These prefixes are used further in the names of some elements (attributes have no prefixes). Remove the definition of the prefix y and for all elements provided with this prefix, replace it with the prefix x, and for all elements provided with the prefix x, replace it with the xml prefix of the XML namespace.

Additional Tasks for Processing XML Documents

In all tasks of this subgroup, it is assumed that a certain namespace is defined in the root element of the source XML document, which applies to all its descendant elements. This namespace must be used for the names of all elements in the transformed document. Namespace prefixes are not used in the tasks of this subgroup.

LinqXml61°. Given an XML document with information about fitness center clients. Sample first-level element:

<record>
  <id>10</id>
  <date>2000-05-01T00:00:00</date>
  <time>PT5H13M</time>
</record>

Here id is the client code (integer), date is the date with information about the year and month, time is the duration of classes (in hours and minutes) of this client during the specified month. Transform the document by changing the first-level elements as follows:

<time id="10" year="2000" month="5">PT5H13M</time>

Do not change the order of the first-level elements.

LinqXml62°. Given an XML document with information about fitness center clients. Sample first-level element (data meaning the same as in LinqXml61):

<time year="2000" month="5" id="10">PT5H13M</time>

Transform the document by changing the first-level elements as follows:

<id10 date="2000-05-01T00:00:00">313</id10>

The element name must have the prefix id, after which the client code is specified; in the value of the date attribute, the day must be 1, and the time must be zero. The value of the element is the duration of the client's classes in this month, converted to minutes. Elements must be sorted in ascending order of client code, and for identical code values — in ascending order of date.

LinqXml63°. Given an XML document with information about fitness center clients. Sample first-level element (data meaning the same as in LinqXml61):

<record date="2000-05-01T00:00:00" id="10" time="PT5H13M" />

Transform the document by grouping data by client codes and changing the first-level elements as follows:

<client id="10">
  <time year="2000" month="5">PT5H13M</time>
  …
</client>

First-level elements must be sorted in ascending order of client code, their child elements — in ascending order of year number, and for identical year values — in ascending order of month number.

LinqXml64°. Given an XML document with information about fitness center clients. Sample first-level element (data meaning the same as in LinqXml61):

<client id="10">
  <date>2000-05-01T00:00:00</date>
  <time>PT5H13M</time>
</client>

Transform the document by grouping data by years, and within each year — by months. Change the first-level elements as follows:

<y2000>
  <m5>
    <client id="10" time="313" />
    …
  </m5>
  …
</y2000>

The name of the first-level element must have the prefix y, after which the year number is specified; the name of the second-level element must have the prefix m, after which the month number is specified. The time attribute must contain the duration of classes in minutes. First-level elements must be sorted in descending order of year number, their child elements — in ascending order of month number. Third-level elements having a common parent must be sorted in ascending order of client codes.

LinqXml65°. Given an XML document with information about fitness center clients. Sample first-level element (data meaning the same as in LinqXml61, data grouped by client codes; client codes, provided with the prefix id, are specified as names of first-level elements):

<id10>
  <info>
    <date>2000-05-01T00:00:00</date>
    <time>PT5H13M</time>
  </info>
  …
</id10>

Transform the document by grouping data by years and changing the first-level elements as follows:

<year value="2000">
  <total-time id="10">860</total-time>
  …
</year>

The value of the second-level element must be equal to the total duration of classes (in minutes) of the client with the specified code during the specified year. First-level elements must be sorted in ascending order of year number, their child elements — in ascending order of client codes.

LinqXml66°. Given an XML document with information about fitness center clients. Sample first-level element (data meaning the same as in LinqXml61, data grouped by client codes):

<client id="10">
  <info date="2000-05-01T00:00:00" time="PT5H13M" />
  …
</client>

Transform the document by grouping data by years and months and leaving information only about those months in which at least three clients attended classes. Change the first-level elements as follows:

<d2000-5 total-time="956" client-count="3">
  <id10 time="313" />
  …
</d2000-5>

The name of the first-level element must have the prefix d, after which the year number and, after a hyphen, the month number are specified (insignificant zeros are not displayed). The name of the second-level element must have the prefix id, after which the client code is specified. The total-time attribute must contain the total duration of classes (in minutes) of all clients in this month, the client-count attribute — the number of clients who trained in this month. The time attribute for second-level elements must contain the duration of classes (in minutes) of the client with the specified code in this month. First-level elements must be sorted in ascending order of year number, and for identical year numbers — in ascending order of month number; their child elements must be sorted in ascending order of client codes.

LinqXml67°. Given an XML document with information about fitness center clients. Sample first-level element (data meaning the same as in LinqXml61):

<client id="10" time="PT5H13M">
  <year>2000</year>
  <month>5</month>
</client>

Transform the document by grouping data by years and months and changing the first-level elements as follows:

<y2000>
  <m1 total-time="0" client-count="0" />
  …
  <m5 total-time="956" client-count="3" />
  …
</y2000>

The name of the first-level element must have the prefix y, after which the year number is specified; the name of the second-level element must have the prefix m, after which the month number is specified. The total-time attribute must contain the total duration of classes (in minutes) of all clients in this month, the client-count attribute — the number of clients who trained in this month. Each first-level element must contain second-level elements corresponding to all months of the year; if no classes were held in any month, then the attributes for that month must have zero values. First-level elements must be sorted in ascending order of year number, their child elements — in ascending order of month number.

Note. To efficiently form sequences related to all months, use the auxiliary sequence Enumerable.Range(1, 12) and the GroupJoin method.

LinqXml68°. Given an XML document with information about gasoline prices at gas stations. Sample first-level element:

<record>
  <company>Leader</company>
  <street>Chekhov-St.</street>
  <brand>92</brand>
  <price>2200</price>
</record>

Here street is the street name, company is the company name (street and company names do not contain spaces and are valid XML names), brand is the gasoline brand (numbers 92, 95, or 98), price is the price of 1 liter of gasoline (integer). Each company has no more than one gas station on each street, prices at different gas stations of the same company may vary. Transform the document by changing the first-level elements as follows:

<station company="Leader" street="Chekhov-St.">
  <info>
    <brand>92</brand>
    <price>2200</price>
  </info>
</station>

Do not change the order of the first-level elements.

LinqXml69°. Given an XML document with information about gasoline prices at gas stations. Sample first-level element (data meaning the same as in LinqXml68):

<station company="Leader">
  <info street="Chekhov-St.">
    <brand>92</brand>
    <price>2200</price>
  </info>
</station>

Transform the document by changing the first-level elements as follows:

<b92 company="Leader" street="Chekhov-St." price="2200" />

The element name must have the prefix b, after which the gasoline brand is specified. Elements are represented as combined tags and must be sorted in ascending order of gasoline brands, for identical brands — in alphabetical order of company names, and for identical companies — in alphabetical order of street names.

LinqXml70°. Given an XML document with information about gasoline prices at gas stations. Sample first-level element (data meaning the same as in LinqXml68):

<station brand="98" price="2850">
  <company>Leader</company>
  <street>Aviators-St.</street>
</station>

Transform the document by grouping data by company names, and within each company — by gasoline brands. Change the first-level elements as follows:

<company name="Leader">
  <brand value="98">
    <price street="Aviators-St.">2850</price>
    …
  </brand>
  …
</company>

First-level elements must be sorted in alphabetical order of company names, and their child elements — in descending order of gasoline brands. Third-level elements having a common parent must be sorted in alphabetical order of street names.

LinqXml71°. Given an XML document with information about gasoline prices at gas stations. Sample first-level element (data meaning the same as in LinqXml68):

<station street="Aviators-St." company="Leader">
  <info brand="98" price="2850" />
</station>

Transform the document by grouping data by gasoline brands, and within each brand — by prices of 1 liter of gasoline. Change the first-level elements as follows:

<b98>
  <p2850>
    <info street="Aviators-St." company="Leader" />
    …
  </p2850>
  …
</b98>

The name of the first-level element must have the prefix b, after which the gasoline brand is specified; the name of the second-level element must have the prefix p, after which the price of 1 liter of gasoline is specified. First-level elements must be sorted in descending order of gasoline brands, and their child elements — in descending order of prices. Third-level elements having a common parent must be sorted in alphabetical order of street names, and for identical streets — in alphabetical order of company names.

LinqXml72°. Given an XML document with information about gasoline prices at gas stations. Sample first-level element (data meaning the same as in LinqXml68, data grouped by company names; company names are specified as names of first-level elements):

<Leader>
  <price street="Chekhov-St." brand="92">2200</price>
  …
</Leader>

Transform the document by grouping data by street names, and within each street — by gasoline brands. Change the first-level elements as follows:

<Chekhov-St.>
  <b92>
    <min-price company="Premier-oil">2050</min-price>
    …
  </b92>
  …
</Chekhov-St.>

The name of the first-level element coincides with the street name, the name of the second-level element must have the prefix b, after which the gasoline brand is specified. The value of the third-level element is the minimum price of gasoline of this brand on this street, its company attribute contains the name of the company at whose gas station the minimum price is offered. First-level elements must be sorted in alphabetical order of street names, and their child elements — in ascending order of gasoline brands. If there are several third-level elements having a common parent (this means that on one street there are several gas stations where gasoline of this brand has the minimum price), then these elements must be sorted in alphabetical order of company names.

LinqXml73°. Given an XML document with information about gasoline prices at gas stations. Sample first-level element (data meaning the same as in LinqXml68, data grouped by street names; street names are specified as names of first-level elements):

<Chekhov-St.>
  <company name="Leader">
    <brand>92</brand>
    <price>2200</price>
  </company>
  …
</Chekhov-St.>

Transform the document by grouping data by company names and street names and leaving information only about those gas stations that offer at least two gasoline brands. Change the first-level elements as follows:

<Leader\Chekhov-St. brand-count="2">
  <b92 price="2200" />
  <b95 price="2450" />
</Leader\Chekhov-St.>

The name of the first-level element contains the company name, followed by an underscore and the street name; the name of the second-level element must have the prefix b, after which the gasoline brand is specified. The brand-count attribute must contain the number of gasoline brands offered at this gas station. First-level elements must be sorted in alphabetical order of company names, and for identical company names — in alphabetical order of street names; their child elements must be sorted in ascending order of gasoline brands.

LinqXml74°. Given an XML document with information about gasoline prices at gas stations. Sample first-level element (data meaning the same as in LinqXml68, gasoline brands, provided with the prefix brand, are specified as names of first-level elements; the station attribute contains the street and company names, separated by an underscore):

<brand92 station="Chekhov-St.\Leader" price="2200" />

Transform the document by grouping data by company names and changing the first-level elements as follows:

<Leader>
  <Sadovaya-St. brand92="0" brand95="0" brand98="0" />
  <Chekhov-St. brand92="2200" brand95="2450" brand98="0" />
  …
</Leader>

The name of the first-level element coincides with the company name, the name of the second-level element coincides with the street name. The attributes of the second-level elements have the prefix brand, after which the gasoline brand is specified; their value is the price of 1 liter of gasoline of the specified brand or the number 0 if gasoline of the specified brand is not offered at this gas station. For each company, information should be output for every street present in the source document, even if this street lacks a gas station of this company (in this case, the values of all brand attributes should be 0). First-level elements must be sorted in alphabetical order of company names, and their child elements — in alphabetical order of street names.

LinqXml75°. Given an XML document with information about gasoline prices at gas stations. Sample first-level element (data meaning the same as in LinqXml68, company and street names, separated by an underscore, are specified as names of first-level elements):

<Leader\Chekhov-St.>
  <brand>92</brand>
  <price>2200</price>
</Leader\Chekhov-St.>

Transform the document by grouping data by street names and changing the first-level elements as follows:

<Chekhov-St.>
  <brand98 station-count="0">0</brand98>
  <brand95 station-count="0">0</brand95>
  <brand92 station-count="3">2255</brand92>
</Chekhov-St.>

The name of the first-level element coincides with the street name, the name of the second-level element has the prefix brand, after which the gasoline brand is specified. The station-count attribute is equal to the number of gas stations located on this street and offering gasoline of this brand; the value of the second-level element is the average price of 1 liter of gasoline of this brand across all gas stations located on this street. The average price is found by the following formula: "total price across all stations" / "number of stations", where the "/" operation denotes integer division. If there are no gas stations on this street offering gasoline of this brand, then the value of the corresponding second-level element and the value of its station-count attribute must be 0. First-level elements must be sorted in alphabetical order of street names, and their child elements — in descending order of gasoline brands.

LinqXml76°. Given an XML document with information about utility payment debts. Sample first-level element:

<record>
  <house>12</house>
  <flat>129</flat>
  <name>Sergeev T.M.</name>
  <debt>1833.32</debt>
</record>

Here house is the house number (integer), flat is the apartment number (integer), name is the tenant's last name and initials (initials do not contain spaces and are separated from the last name by one space), debt is the amount of debt as a fractional number (insignificant zeros are not specified). All houses are 144-apartment buildings, have 9 floors and 4 entrances; on each floor in each entrance there are 4 apartments. Transform the document by changing the first-level elements as follows:

<debt house="12" flat="129">
  <name>Sergeev T.M.</name>
  <value>1833.32</value>
</debt>

Do not change the order of the first-level elements.

LinqXml77°. Given an XML document with information about utility payment debts. Sample first-level element (data meaning the same as in LinqXml76):

<debt house="12" flat="129" name="Sergeev T.M.">1833.32</debt>

Transform the document by changing the first-level elements as follows:

<address12-129 name="Sergeev T.M." debt="1833.32" />

The element name must have the prefix address, after which the house number and, after a hyphen, the apartment number are specified. Elements are represented as combined tags and must be sorted in ascending order of house numbers, and for identical house numbers — in ascending order of apartment numbers.

LinqXml78°. Given an XML document with information about utility payment debts. Sample first-level element (data meaning the same as in LinqXml76):

<debt house="12" flat="23">
  <name>Ivanov A.V.</name>
  <value>1245.64</value>
</debt>

Transform the document by grouping data by house number, and within each house — by entrance number. Change the first-level elements as follows:

<house number="12">
  <entrance number="1">
    <debt name="Ivanov A.V." flat="23">1245.64</debt>
    …
  </entrance>
  …
</house>

First-level elements must be sorted in ascending order of house numbers, and their child elements — in ascending order of entrance numbers. Third-level elements having a common parent must be sorted in descending order of debt amount (it is assumed that all debt amounts are different). Entrances with no debtors are not displayed.

LinqXml79°. Given an XML document with information about utility payment debts. Sample first-level element (data meaning the same as in LinqXml76):

<house value="12">
  <flat value="129" />
  <name value="Sergeev T.M." />
  <debt value="1833.32" />
</house>

Transform the document by grouping data by house number, and within each house — by floor number. Change the first-level elements as follows:

<house12>
  <floor6>
    <Sergeev\T.M. flat="129" debt="1833.32" />
    …
  </floor6>
  …
</house12>

The name of the first-level element must have the prefix house, after which the house number is specified; the name of the second-level element must have the prefix floor, after which the floor number is specified. The name of the third-level element coincides with the tenant's last name and initials; the last name is separated from the initials by an underscore. First-level elements must be sorted in ascending order of house numbers, and their child elements — in descending order of floor numbers. Third-level elements having a common parent must be sorted in alphabetical order of tenants' last names and initials. Floors with no debtors are not displayed.

LinqXml80°. Given an XML document with information about utility payment debts. Sample first-level element (data meaning the same as in LinqXml76, data grouped by house numbers; as second-level elements, tenants' last names and initials are specified, the last name is separated from the initials by an underscore):

<house number="12">
  <Ivanov\A.V.>
    <flat value="23" />
    <debt value="1245.64" />
  </Ivanov\A.V.>
  …
</house>

Transform the document, preserving the grouping of data by house number, performing grouping within each house by entrance number, and changing the first-level elements as follows:

<house12>
  <entrance1 total-debt="2493.38" count="3">
    <flat23 name="Ivanov A.V." />
    …
  </entrance1>
  …
</house12>

The name of the first-level element must have the prefix house, after which the house number is specified; the name of the second-level element must have the prefix entrance, after which the entrance number is specified; the name of the third-level element must have the prefix flat, after which the apartment number is specified. The total-debt attribute is equal to the total debt of the tenants of this entrance (the debt value must be rounded to two decimal places, insignificant zeros are not displayed), the count attribute is equal to the number of debtors in this entrance. First-level elements must be sorted in ascending order of house numbers, and their child elements — in ascending order of entrance numbers. Third-level elements having a common parent must be sorted in ascending order of apartment numbers. Entrances with no debtors are not displayed.

LinqXml81°. Given an XML document with information about utility payment debts. Sample first-level element (data meaning the same as in LinqXml76, data grouped by house numbers; as names of first-level elements, house numbers are specified, provided with the prefix house, and as names of second-level elements — apartment numbers, provided with the prefix flat):

<house12>
  <flat23 name="Ivanov A.V." debt="1245.64" />
  …
</house12>

Transform the document, preserving the grouping of data by house number, performing grouping within each house by entrance number, and leaving information only about those tenants whose debt amount is not less than the average debt amount for this entrance. Change the first-level elements as follows:

<house number="12">
  <entrance number="1" count="4" avr-debt="1136">
    <debt flat="23" name="Ivanov A.V.">1245.64</debt>
    <debt flat="28" name="Sidorov P.K.">1383.27</debt>
  </entrance>
  …
</house>

The count attribute is equal to the number of debtors in this entrance, the avr-debt attribute defines the average debt for this entrance (integer), calculated by the following formula: (int)Math.Round(<total debt>*100)/(<number of debtors>*100) (the "/" symbol denotes the integer division operation). Third-level elements contain information about those tenants whose debt amount is not less than the avr-debt value for this entrance. First-level elements must be sorted in ascending order of house numbers, and their child elements — in ascending order of entrance numbers. Third-level elements having a common parent must be sorted in ascending order of apartment numbers. Entrances with no debtors are not displayed.

LinqXml82°. Given an XML document with information about utility payment debts. Sample first-level element (data meaning the same as in LinqXml76, as the name of the first-level element, the house and apartment numbers are specified, separated by a "-" (hyphen) and provided with the prefix addr, and as the value of this element, the debt amount for this apartment is specified):

<addr12-23>1245.64</addr12-23>

Transform the document by grouping data by house number, and within each house — by floor number. Change the first-level elements as follows:

<house12>
  <floor1 count="0" total-debt="0" />
  …
  <floor6 count="1" total-debt="1245.64" />
  …
  <floor9 count="3" total-debt="3142.7" />
</house12>

The name of the first-level element must have the prefix house, after which the house number is specified; the name of the second-level element must have the prefix floor, after which the floor number is specified. The count attribute is equal to the number of debtors on this floor, the total-debt attribute defines the total debt for this floor, rounded to two decimal places (insignificant zeros are not displayed). If there are no debtors on this floor, then for the corresponding second-level element, the values of the count and total-debt attributes must be 0. First-level elements must be sorted in ascending order of house numbers, and their child elements — in ascending order of floor numbers.

LinqXml83°. Given an XML document with information about student grades in various subjects. Sample first-level element:

<record>
  <class>9</class>
  <name>Stepanova D.B.</name>
  <subject>Physics</subject>
  <mark>4</mark>
</record>

Here class is the class number (integer from 7 to 11), name is the student's last name and initials (initials do not contain spaces and are separated from the last name by one space), subject is the subject name, containing no spaces, mark is the grade (integer in the range from 2 to 5). There are no full namesakes (with matching last name and initials) among the students. Transform the document by changing the first-level elements as follows:

<mark subject="Physics">
  <name class="9">Stepanova D.B.</name>
  <value>4</value>
</mark>

Do not change the order of the first-level elements.

LinqXml84°. Given an XML document with information about student grades in various subjects. Sample first-level element (data meaning the same as in LinqXml83):

<pupil class="9" name="Stepanova D.B.">
  <subject>Physics</subject>
  <mark>4</mark>
</pupil>

Transform the document by changing the first-level elements as follows:

<class9 name="Stepanova D.B." subject="Physics">4</class9>

The element name must have the prefix class, after which the class number is specified. Elements must be sorted in ascending order of class numbers, for identical class numbers — in alphabetical order of students' last names and initials, for each student — in alphabetical order of subject names, and for identical subjects — in ascending order of grades.

LinqXml85°. Given an XML document with information about student grades in various subjects. Sample first-level element (data meaning the same as in LinqXml83):

<info class="9" name="Stepanova D.B." subject="Physics" mark="4" />

Transform the document by grouping data by class number, within each class — by students, and for each student — by subjects. Change the first-level elements as follows:

<class number="9">
  <pupil name="Stepanova D.B.">
    <subject name="Physics">
      <mark>4</mark>
      …
    </subject>
    …
  </pupil>
  …
</class>

First-level elements must be sorted in ascending order of class numbers, and their child elements — in alphabetical order of students' last names and initials. Third-level elements having a common parent must be sorted in alphabetical order of subject names, and fourth-level elements having a common parent must be sorted in descending order of grades.

LinqXml86°. Given an XML document with information about student grades in various subjects. Sample first-level element (data meaning the same as in LinqXml83):

<pupil name="Stepanova D.B." class="9">
  <info mark="4" subject="Physics" />
</pupil>

Transform the document by grouping data by students and changing the first-level elements as follows:

<Stepanova\D.B. class="9">
  <mark4 subject="Physics" />
  …
</Stepanova\D.B.>

The name of the first-level element coincides with the student's last name and initials (the space between the last name and initials is replaced by an underscore), the name of the second-level element must have the prefix mark, after which the grade is specified. First-level elements must be sorted in alphabetical order of students' last names and initials, their child elements — in descending order of grades, and for identical grades — in alphabetical order of subject names.

LinqXml87°. Given an XML document with information about student grades in various subjects. Sample first-level element (data meaning the same as in LinqXml83, data grouped by students):

<pupil name="Stepanova D.B." class="9">
  <mark subject="Physics">4</mark>
  …
</pupil>

Transform the document by grouping data by subject names and changing the first-level elements as follows:

<Physics>
  <class9>
    <mark-count>4</mark-count>
    <avr-mark>4.1</avr-mark>
  </class9>
  …
</Physics>

The name of the first-level element coincides with the subject name, the name of the second-level element must have the prefix class, after which the class number is specified. The value of the mark-count element is equal to the number of grades in this subject given in this class; the value of the avr-mark element is equal to the average value of these grades, found by the following formula: (<sum of grades>*10/<number of grades>)*0.1 (the "/" symbol denotes the integer division operation, the obtained value must contain no more than one decimal place, insignificant zeros are not displayed). First-level elements must be sorted in alphabetical order of subject names, and their child elements — in ascending order of class numbers. For each subject, display only those classes in which at least one grade in this subject has been given.

LinqXml88°. Given an XML document with information about student grades in various subjects. Sample first-level element (data meaning the same as in LinqXml83, data grouped by classes):

<class number="9">
  <pupil name="Stepanova D.B." subject="Physics" mark="4" />
  …
</class>

Transform the document by grouping data by subjects and leaving information only about those students who received more than two grades in this subject. Change the first-level elements as follows:

<subject name="Physics">
  <pupil class="9" name="Stepanova D.B." m1="4" m2="3" m3="3" />
  …
</subject>

The grades of each student in this subject are specified in attributes having the prefix m, after which the ordinal number of the grade follows. First-level elements must be sorted in alphabetical order of subject names, their child elements — in ascending order of class numbers, and for identical classes — in alphabetical order of students' last names and initials. Grades for each student must be arranged in descending order. If for some subject no students are found who have more than two grades in it, then the corresponding first-level element must be represented as a combined tag, for example:

<subject name="Chemistry" />

LinqXml89°. Given an XML document with information about student grades in various subjects. Sample first-level element (data meaning the same as in LinqXml83, as names of first-level elements, students' last names and initials are specified; here the space between the last name and initials is replaced by an underscore):

<Petrov\S.N. class="11" subject="Physics">4</Petrov\S.N.>

Transform the document by grouping data by subjects, and for each subject — by classes. Change the first-level elements as follows:

<Physics>
  <class7 pupil-count="0" mark-count="0" />
  …
  <class11 pupil-count="3" mark-count="5" />
</Physics>

The name of the first-level element coincides with the subject name, the name of the second-level element must have the prefix class, after which the class number is specified. The value of the pupil-count attribute is equal to the number of students of this class who have at least one grade in this subject, the value of the mark-count attribute is equal to the number of grades in this subject in this class. For each subject, information must be output for every class (from 7 to 11); if in some class no student was surveyed in this subject, then the pupil-count and mark-count attributes must be 0. First-level elements must be sorted in alphabetical order of subject names, and their child elements — in ascending order of class numbers.

LinqXml90°. Given an XML document with information about student grades in various subjects. Sample first-level element (data meaning the same as in LinqXml83; as names of first-level elements, students' last names with initials and class numbers are specified; between the last name and initials an underscore is indicated, and between the initials and the class number — a hyphen):

<Stepanova\D.B.-9 subject="Physics" mark="4" />

Transform the document by grouping data by class numbers, and for each class — by students. Change the first-level elements as follows:

<class9>
  <Stepanova\D.B.>
    <History count="0">0</History>
    …
    <Physics count="3">3.3</Physics>
  </Stepanova\D.B.>
  …
</class9>

The name of the first-level element must have the prefix class, after which the class number is specified, the name of the second-level element coincides with the student's last name and initials, between which an underscore is indicated. The name of the third-level element coincides with the subject name. The value of the count attribute is equal to the number of grades in this subject received by this student. The value of the third-level element is equal to the average grade in this subject for this student; the average grade is computed by the following formula: (<sum of grades>*10/<number of grades>)*0.1 (the "/" symbol denotes the integer division operation, the obtained value must contain no more than one decimal place, insignificant zeros are not displayed). For each student, information must be output for every subject included in the source XML document; if a student has no grades in some subject, then the value of the corresponding third-level element and the value of its count attribute must be 0. First-level elements must be sorted in ascending order of class numbers, and their child elements — in alphabetical order of students' last names. Third-level elements having a common parent must be sorted in alphabetical order of subject names.


PrevNext

 

  Ðåéòèíã@Mail.ru

Designed by
M. E. Abramyan and V. N. Braguilevsky

Last revised:
01.01.2026