{"record":{"id":"4b56a4c5a71397e0","repo":"wmjordan/PDFPatcher","slug":"error-4b56a4","errorCode":null,"errorMessage":"“[]”筛选表达式前缺少节点名称。","messagePattern":"“\\[\\]”筛选表达式前缺少节点名称。","errorType":"validation","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"App/Model/PdfPath/PathCompiler.cs","lineNumber":80,"sourceCode":"\t\t\t}\r\n\t\t\telse if (c == SelfChar) {\r\n\t\t\t\tif (MatchNextChar(path, length, index, SelfChar)) {\r\n\t\t\t\t\t++index;\r\n\t\t\t\t\treturn PathAxisType.Parent;\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\treturn PathAxisType.None;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\treturn PathAxisType.Children;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tprivate static string ExtractName(string path, int length, ref int index) {\r\n\t\t\tchar c = path[index];\r\n\t\t\tif (__PredicateChars.Contains(c)) {\r\n\t\t\t\tthrow new FormatException(\"“[]”筛选表达式前缺少节点名称。\");\r\n\t\t\t}\r\n\t\t\tif (c == UniversalName) {\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\t\t\tvar n = new List<char>();\r\n\t\t\twhile (Char.IsLetter(c) || n.Count > 0 && Char.IsLetterOrDigit(c)) {\r\n\t\t\t\tn.Add(c);\r\n\t\t\t\t++index;\r\n\t\t\t\tif (index < length) {\r\n\t\t\t\t\tc = path[index];\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn n.Count > 0 ? new String(n.ToArray()) : null;\r\n\t\t}\r\n\r","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/wmjordan/PDFPatcher/blob/4782bbd9ada850b56258f29999b7a1c9076c9b1b/App/Model/PdfPath/PathCompiler.cs#L62-L98","documentation":"PathCompiler.ExtractName throws FormatException when the character at the current index is '[' or ']' — i.e. when the parser expects a node name but finds a predicate delimiter. This differs from error [4]: here the axis was already consumed and the parser moved on to read the name, but the name position is occupied by a bracket, so the name is missing.","triggerScenarios":"Calling PathCompiler.Compile with a path where an axis separator ('/', '//', '.') is immediately followed by a predicate bracket, e.g. \"/Page//[1]\" or \"..[1]\" — the axis parsed but ExtractName sees '['. Also occurs for \"/Page/[1]\" sequences where a name was expected but a bracket appeared.","commonSituations":"Dynamically concatenating path segments and emitting an axis without the following node name; malformed user input; a double-slash descendants axis not followed by a name before a filter.","solutions":["Ensure every axis token ('/', '//', '.', '..') is followed by a node name or '*' before any predicate.","Validate the compiled path expression by testing it against a sample document before deployment.","When constructing paths, insert the node name ('*' for universal) between the axis and any '[' filter."],"exampleFix":"// before\nvar expr = PathCompiler.Compile(\"// [1]\");\n\n// after\nvar expr = PathCompiler.Compile(\"//*[1]\");","handlingStrategy":"validation","validationCode":"if (path.Contains(\"/[\") || path.Contains(\"//[\") || path.Contains(\".[\"))\n    throw new ArgumentException(\"Axis must be followed by a node name before a predicate.\");","typeGuard":"static bool PathHasNameBeforePredicate(string p) =>\n    !System.Text.RegularExpressions.Regex.IsMatch(p, @\"(/|//|\\.)\\[\");","tryCatchPattern":"try { var e = PathCompiler.Compile(path); }\ncatch (FormatException ex) { /* missing node name */ }","preventionTips":["Insert a node name or '*' between any axis token and a '[' predicate.","Validate dynamically assembled paths before use."],"tags":["validation","pdfpath","format","parsing"],"backgroundTag":null,"analyzedSha":"4782bbd9ada850b56258f29999b7a1c9076c9b1b","analyzedAt":"2026-08-13T17:44:50.812Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}