What's New in System.Xml

The following System.Xml features are new in the .NET Framework: XmlConvert methods to support W3C fourth edition.

New XmlConvert Methods

New members of the XmlConvert class allow for specific characters and strings to be validated as particular XML tokens or as valid XML:

public static bool IsNCNameChar(char);
public static bool IsPublicIdChar(char);
public static bool IsStartNCNameChar(char);
public static bool IsWhitespaceChar(char);
public static bool IsXmlChar(char);
public static bool IsXmlSurrogatePair(char, char);
public static string VerifyPublicId(string);
public static string VerifyWhitespace(string);
public static string VerifyXmlChars(string);

Breaking Changes in Visual Studio 2010

The following sections are the breaking changes in System.Xml:

  • The XslCompiledTransform class could throw a NullReferenceException when loading a stylesheet.

  • XmlNode.InnerText could throw a NullReferenceException.

  • The XmlValidatingReader class could throw a NullReferenceException when some arguments to its constructor were null.

These have been changed to throw more useful exceptions and to make it easier to debug code.

XmlWriter.Dispose No Longer Suppresses All Exceptions

XmlWriter.Dispose formerly suppressed all exceptions (including exceptions that should not be caught, such as an OutOfMemoryException). XmlWriter.Dispose has been changed to throw useful exceptions.

Chameleon Schemas Now Cloned Correctly When Included by Multiple Schemas

Schemas that don't have a target namespace (also called chameleon schemas, formerly included common types into a schema) take the target namespace of the importing schema when they are included in another XSD.

If two schemas were in an XmlSchemaSet and both schemas included the chameleon schema, the chameleon schema was not cloned correctly into both schemas. This affected XML validation. The incorrect validation could result in data corruption.

The cloning now works as expected.

XsdValidatingReader.MoveToNextAttribute Now Works Correctly After a Call to MoveToAttribute(Int32)

A bug in XsdValidatingReader.MoveToAttribute(Int32) caused MoveToNextAttribute to fail because the current attribute index was never updated. This prevented polymorphism from working with different subclasses of XsdReader.

XsdValidatingReader.MoveToNextAttribute will now work correctly after a call to MoveToAttribute(Int32).

XmlReader.ReadContentAs No Longer Ignores Passed in an IXmlNamespaceResolver

The XmlReader.ReadContentAs method that accepts a IXmlNamespaceResolver will now use the IXmlNamespaceResolver parameter as the namespace resolver. Previously, the IXmlNamespaceResolver parameter was ignored and XmlReader was used for the namespace resolver.

The Function-available XSLT Function Now Works Even If the Function to Test is Never Called

The function-available function is used to determine whether a function with a particular name is available for use. Previously, if the function was not called in the XSLT, function-available always returned false, even if the function was available. This same error was fixed in MSXML3 SP1.

Dependency Bugs in XmlSchemaSet Have Been Fixed

XmlSchemaSet allows XSD schemas to be compiled. These schemas can include other schemas (A.xsd can include B.xsd which can include C.xsd). Compiling any of these schemas causes the dependency graph to be traversed. Previously, when a schema in the set was modified, and a dependant schema was recompiled or reprocessed, the dependency graph of schemas was not correctly traversed, leading to inconsistent compiled schemas.

XmlReader.Create Returned a Reader that Incorrectly Discarded Significant Whitespace

XML validation recognizes a mixed content mode containing text and XML markup. In mixed mode, all whitespace is significant and should be reported. Previously, the XsdValidatingReader reported significant whitespace as not significant.

The previous behavior could result in data loss when the data was loaded to an XmlDocument or XDocument/XElement that strips non-significant white space by default.

Wrapping XmlWriters Did Not Respect NewLineHandling.None

If you created a wrapping XmlWriter (an XmlWriter that writes to another XmlWriter) and specified that the wrapping XmlWriter has NewLineHandling.None, when you used the WriteChars method, and the content contained /r/n, the output contained /r/n/r/n (data corruption). There are two common scenarios that were affected by this behavior.

  • When using an existing XmlWriter created from an XmlSerializer, and then wrapping that writer. If the consumer of the generated XML was not whitespace tolerant (for example, a third party Web service), there could be unexpected behavior.

  • When using an XmlWriter to insert content into an existing XmlDocument or XDocument. The previous behavior would not let you correctly normalize newlines on content added to the document.

With this fix, NewLineHandling.None has the correct behavior for a wrapping writer.

In the XmlWriter, Entity References were Entitized Twice in XML Attributes

If the user attempted to write an Entity into an xmlns attribute or into an xml:lang or xml:space attribute using the XmlWriter.WriteEntityRef, the entity was entitized twice in the output, corrupting the data.

XmlWriter w = XmlWriter.Create(Console.Out);

w.WriteDocType("root", null, null, "<!ENTITY e \"en-us\">");
w.WriteStartElement("root");
w.WriteStartAttribute("xml", "lang", null);
w.WriteEntityRef("e");
w.WriteEndAttribute();
w.WriteEndElement();
w.Close();

Output:

<!DOCTYPE root [<!ENTITY e "en-us">]><root xml:lang="&amp;e;" \>

Expected:

<!DOCTYPE root [<!ENTITY e "en-us">]><root xml:lang="&e;" \>

Now, the entity is not entitized twice.

XNode.CreateReader Returns the Correct BaseURI

If you created an XmlReader object from a LINQ to XML class using CreateReader, the reader did not return the correct BaseURI until Read was called at least once. As a result, code depending on the value of the BaseURI before the first Read call will change after Read is called, either directly from your code or from another call, like passing the XmlReader to another method.

Using XSLT with LINQ to XML, the XSLT ID Function Now Returns the Correct Value

If you create an XmlReader from a LINQ to XML class by using the CreateReader function, and this XmlReader is passed to an XSLT, any instances of the ID function in the XSLT previously returned null. Null is not a valid return value for the ID function. Any code that depends on the value of ID being null will need to be changed.

DocumentXPathNavigator Now Correctly Reports the Local Name of the x:xmlns Attribute

DocumentXPathNavigator previously returned an empty string for the local name of the x:xmlns attribute. The previous behavior could cause data corruption and prevent using XSLT to generate XSLTs in certain circumstances.

The local name is now returned correctly, enabling XSLTs, code that generates other XSLTs, or documents that return the use of x:xmlns.

XsltReader and XmlReader on a Sub-Tree Does Not Create Duplicate Namespace Declarations within One XML Element

When reading an XSLT with an XsltReader, if an XmlReader is laid on the XsltReader, the resulting XML element contained duplicate namespace declarations, which is invalid XML and could cause problems with some XML processors.

This previous behavior could cause data corruption and prevent the creation of valid XML from the XmlReader.

See Also

Concepts

What's New in the .NET Framework 4

What's New in Visual Studio 2010

Other Resources

XML Documents and Data