Best way to get InnerXml of an XElement?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
XElement is part of LINQ to XML, which deliberately does not expose the old DOM-style InnerXml property. If you want the XML inside an element, the correct approach is usually to serialize that element's child nodes, not the element itself and not only its text.
Why XElement Has No InnerXml
Developers often come from XmlDocument, where XmlNode.InnerXml is a built-in property. LINQ to XML has a different design. It models XML as strongly typed nodes such as XElement, XText, and XComment, and expects you to work with those nodes directly.
That means there are three different questions you might be asking:
- "Give me only the text content."
- "Give me the child nodes as XML."
- "Give me the entire element including the outer tag."
Those are not the same result, so it is important to choose the right API.
The Usual Answer: Concatenate Nodes()
If you want the equivalent of inner XML, use Nodes() and serialize the child nodes.
Output:
This is usually the best answer because it preserves child elements, comments, and mixed content exactly as nodes.
Do Not Use Value Unless You Only Want Text
Value looks tempting, but it returns only the concatenated text content. It strips markup completely.
Output:
That is useful for plain text extraction, but it is not inner XML. If your caller needs the nested tags, Value is the wrong tool.
ToString() Gives Outer XML
At the other extreme, calling ToString() on the element gives you the outer XML, including the element's own start and end tag.
Output:
So the rule is straightforward:
- '
element.Valuegives text only' - '
element.ToString(...)gives outer XML' - '
string.Concat(element.Nodes()...)gives inner XML'
A Reusable Helper Method
If this comes up often, hide the pattern behind an extension method.
Usage:
This keeps calling code readable and makes the intent obvious.
When an XmlWriter Is Useful
If you need more control over how the output is written, you can stream the child nodes through an XmlWriter. That is more verbose, but useful when you want precise writer settings.
For most cases, string.Concat(element.Nodes()...) is simpler. Reach for the writer approach only when formatting or streaming behavior matters.
Mixed Content Works Correctly
One reason Nodes() is the right abstraction is that XML may contain mixed content, not just child elements. For example:
The children are:
- a text node with
Hello - an element node
b - another text node with
, friend.
Using Nodes() preserves all of that. Using Elements() would lose the text nodes. Using Value would lose the markup.
Common Pitfalls
- Using
Valueand expecting markup to be preserved.Valuereturns text, not XML. - Using
ToString()and accidentally returning outer XML. That includes the current element's tag as well. - Using
Elements()instead ofNodes().Elements()returns child elements only and drops text or comments. - Forgetting
SaveOptions.DisableFormatting. Default serialization may insert indentation or line breaks that were not intended. - Reaching for
XmlDocument.InnerXmlhabits in LINQ to XML code.XElementis a different API with a different model.
Summary
- '
XElementhas no built-inInnerXmlproperty.' - The normal LINQ to XML equivalent is
string.Concat(element.Nodes().Select(...)). - Use
Valueonly when you want text content without markup. - Use
ToString()only when you want outer XML, including the current tag. - Wrap the
Nodes()pattern in an extension method if the operation appears often in your codebase.

