When importing records containing SQL Server XML columns into Excel, data refreshes frequently halt with the error: DataFormat.Error: An XML parsing error occurred. In other cases, the query completes, but the column displays nested [Table] or [Record] objects that cause errors when expanded, or the sheet fails to load entirely due to XML validation breaks.
In SQL Server, the XML data type stores structured or semi-structured markup based on strict W3C standards. When Excel imports these records via Power Query, OLE DB, or ODBC, parsing failures occur because of unescaped entity references (&, <, >), non-printable ASCII characters within the markup, undeclared XML namespaces, or “XML fragments” that lack a single enclosing root element.
Quick Fix: Sanitize and Parse SQL XML Correctly
If the column contains XML fragments, wrap the data in a root node in your SQL query using
CAST('<root>' + CAST(XmlCol AS NVARCHAR(MAX)) + '</root>' AS XML). If the error is caused by invalid characters or nested parsing, extract the required values inside SQL using.value()and.nodes()methods, or cast the column toNVARCHAR(MAX)and process it in Power Query usingXml.Document(Text.Clean([XmlCol])).
Common Causes of XML Parsing Failures in Excel
Excel processes imported XML through strict validation parsers. If the incoming payload deviates from standard document rules, the connection breaks:
- XML Fragments (Missing Root Element): Standard XML parsers require every document to possess exactly one parent root element. SQL Server allows
XMLcolumns to store “fragments” (e.g.,<item>A</item><item>B</item>). When Power Query’sXml.Document()reads this without an enclosing<root>, it throwsDataFormat.Error: Root element is missing. - Non-Printable ASCII Control Bytes: Web forms and legacy feeds often save hidden control characters (ASCII 0 through 31) into database text. When wrapped in XML, characters like
CHAR(0)(null) orCHAR(11)(vertical tab) violate OpenXML specifications, triggering Fixing “Invalid Cell Value” when SQL returns non-printable ASCII characters.. - Undeclared XML Namespaces: If your XML elements utilize prefixes (such as
<ns:Order>) without an explicitxmlns:ns="http://..."attribute defined within the fragment, the parser stops with an undeclared namespace error. - Buffer Truncation: Large XML records stored in
XMLorNVARCHAR(MAX)fields that exceed driver memory limits can be cut off mid-tag (e.g.,<Description>Produc...). The unclosed tag breaks parsing, a symptom detailed in Fixing “Truncated Data” errors when importing SQL VARCHAR(MAX) columns..
[SQL Server XML Column]
│
├── Well-Formed (<root><tag>Val</tag></root>) ──► Parses cleanly via Xml.Document()
│
├── XML Fragment (<tag>A</tag><tag>B</tag>) ────► FAILS: Missing Root Element
│
├── Contains Control Byte (ASCII < 32) ────────► FAILS: Invalid Character
│
└── Undeclared Namespace (<ns:tag>Val</ns:tag>) ─► FAILS: Namespace Resolution
Diagnostic Steps: Locating Malformed XML
Before implementing a fix, determine whether the problem is structural, character-based, or volume-based:
Step 1: Validate Document Well-Formedness in SQL
Execute this test query in SQL Server Management Studio to locate malformed fragments:
SELECT
RecordID,
XmlData
FROM Production.OrderXml
WHERE
-- Check if wrapping in a root resolves parsing
TRY_CAST('<root>' + CAST(XmlData AS NVARCHAR(MAX)) + '</root>' AS XML) IS NULL
AND XmlData IS NOT NULL;
If rows appear, those records contain illegal characters, unescaped ampersands (&), or malformed closing tags that cannot be parsed as XML under any circumstance.
Step 2: Inspect the Power Query Error Step
Open Power Query, navigate to the step where the error surfaces, and click the white space next to the red Error link:
- “Root element is missing”: The column contains XML fragments or empty strings (
""). - “The prefix ‘xyz’ is not defined”: The data has unresolved namespace prefixes. Review Troubleshooting XML Namespace errors in Power Query..
- “An invalid character was found”: Hidden ASCII control characters are embedded in the text nodes.
Step-by-Step Remediation Methods
Method 1: Relational Extraction at the SQL Level (Recommended)
The most reliable approach is to extract the required XML elements into standard relational columns before sending the data to Excel. This offloads XML parsing to SQL Server and avoids Power Query overhead entirely:
SELECT
RecordID,
-- Extract scalar attributes using XQuery .value()
XmlPayload.value('(/Order/@ID)[1]', 'INT') AS OrderID,
XmlPayload.value('(/Order/Customer/text())[1]', 'NVARCHAR(100)') AS CustomerName,
XmlPayload.value('(/Order/Total/text())[1]', 'DECIMAL(18,2)') AS TotalAmount
FROM Sales.OrdersXml;
Because the output is delivered as standard integers, text, and decimals, Excel imports the table cleanly without requiring any XML decoding functions.
Method 2: Wrapping XML Fragments in a Synthetic Root Node
If you need to pass raw XML fragments into Power Query, enforce well-formedness by injecting a root element during query extraction:
SELECT
RecordID,
CAST('<root>' + CAST(XmlPayload AS NVARCHAR(MAX)) + '</root>' AS XML) AS WellFormedXml
FROM Sales.OrdersXml;
In Power Query, parse the column using Xml.Document():
let
Source = Sql.Database("DatabaseServer", "SalesDB"),
RawData = Source{[Schema="dbo",Item="OrdersXml"]}[Data],
// Parse the well-formed XML column
ParsedXml = Table.AddColumn(RawData, "CustomXml", each Xml.Document([WellFormedXml])),
// Remove the synthetic root to access child elements
ExpandedRoot = Table.ExpandTableColumn(ParsedXml, "CustomXml", {"Name", "Value"}, {"NodeName", "NodeValue"})
in
ExpandedRoot
Method 3: Sanitizing Control Characters in Power Query
If the database contains unescaped text or illegal control characters that break the parser, clean the string before invoking Xml.Document:
let
Source = Sql.Database("DatabaseServer", "SalesDB"),
RawTable = Source{[Schema="dbo",Item="RawLogs"]}[Data],
// Cast to text to allow string cleaning
ConvertToString = Table.TransformColumnTypes(RawTable, {{"XmlColumn", type text}}),
// Strip non-printable ASCII control characters
CleanedText = Table.TransformColumns(ConvertToString, {{"XmlColumn", Text.Clean, type text}}),
// Parse safe XML strings
ParseXml = Table.TransformColumns(CleanedText, {{"XmlColumn", each try Xml.Document(_) otherwise null}})
in
ParseXml
Wrapping the parsing routine in try ... otherwise null ensures that an individual corrupt row does not crash the entire dataset refresh.
Verification and Downstream Stability
To confirm that your XML import pipeline is secure:
- Audit Failed Rows: In Power Query, filter the parsed column for
nullvalues after applying thetry ... otherwisestep to isolate corrupt records for database remediation. - Expansion Verification: Expand the resulting table column. Confirm that element attributes and child values align into their designated columns rather than throwing
#VALUE!or#CALC!errors.
If your database workflows involve extracting structured attributes from JSON payloads rather than XML, consult Handling “JSON” string expansion errors from SQL FOR JSON outputs.. For structural repair strategies when an Excel file becomes corrupted by external markup, see How to recover a “Corrupt” Excel file using the XML extraction method. and SQL-to-Excel Data Mapping: Fixing Type Mismatches and Schema Breaks..