{"record":{"id":"fce142c08c950495","repo":"dotnet/wpf","slug":"emptyelement-emptyelement-directive-attribute","errorCode":null,"errorMessage":"EmptyElement ::= . EMPTYELEMENT DIRECTIVE* ATTRIBUTE*.","messagePattern":"EmptyElement ::= \\. EMPTYELEMENT DIRECTIVE\\* ATTRIBUTE\\*\\.","errorType":"exception","errorClass":"XamlUnexpectedParseException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Parser/XamlPullParser.cs","lineNumber":125,"sourceCode":"                foreach (XamlNode node in P_ElementBody())\n                {\n                    yield return node;\n                }\n\n                break;\n            default:\n                throw new XamlUnexpectedParseException(_xamlScanner, nodeType, ElementRuleException);\n            }\n        }\n\n        ///////////////////////////\n        //  EmptyElement ::= EMPTYELEMENT DIRECTIVE* ATTRIBUTE*\n        //\n        public IEnumerable<XamlNode> P_EmptyElement()\n        {\n            if (_xamlScanner.NodeType != ScannerNodeType.EMPTYELEMENT)\n            {\n                throw new XamlUnexpectedParseException(_xamlScanner, _xamlScanner.NodeType,\n                    EmptyElementRuleException);\n            }\n\n            yield return Logic_StartObject(_xamlScanner.Type, _xamlScanner.Namespace);\n            _xamlScanner.Read();\n            if (ProvideLineInfo)\n            {\n                yield return Logic_LineInfo();\n            }\n\n            while (_xamlScanner.NodeType == ScannerNodeType.DIRECTIVE)\n            {\n                // Directives are processed exactly like Attributes.\n                foreach (XamlNode node in LogicStream_Attribute())\n                {\n                    yield return node;\n                }\n","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Parser/XamlPullParser.cs#L107-L143","documentation":"XamlPullParser.P_EmptyElement implements `EmptyElement ::= EMPTYELEMENT DIRECTIVE* ATTRIBUTE*`. It throws XamlUnexpectedParseException when the scanner's current NodeType is not EMPTYELEMENT, since this method may only run when a self-closing element token (<Tag/>) is current. The check enforces the parser's grammar contract that P_Element dispatches to P_EmptyElement only for empty-element tokens.","triggerScenarios":"P_Element dispatching to the empty-element branch while the scanner holds another node type — possible with a custom/injected scanner or reordered node stream; in normal use only from corrupted scanner state or non-well-formed input.","commonSituations":"Custom XamlReader/scanner implementations violating the ScannerNodeType contract; testing harnesses calling P_EmptyElement directly with the wrong current node; parser bugs after scanner state corruption.","solutions":["If using a custom scanner, ensure it sets NodeType to EMPTYELEMENT exactly for self-closing tags.","Do not call P_EmptyElement directly; always go through P_Element which validates the node type.","Validate the XAML is well-formed XML before parsing.","Update to a patched System.Xaml/WPF version if a scanner-state bug is suspected."],"exampleFix":"// before: direct call with wrong node state\nparser.P_EmptyElement();\n\n// after: go through the validating dispatcher\nparser.P_Element();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return XamlReader.Parse(xaml); } catch (XamlUnexpectedParseException ex) { Log($\"Grammar violation at {ex.LineNumber}:{ex.LinePosition}\"); return null; }","preventionTips":["Never call P_EmptyElement outside P_Element","Custom scanners must emit EMPTYELEMENT only for self-closing tags","Add scanner unit tests against the grammar"],"tags":["xaml","parser","grammar","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}