1
2
3
4
5
6 using System;
7
8 namespace System.XPath
9 {
10 public class ExprCounter
11 {
12 public static int GetExprCount()
13 {
14 return exprCount++;
15 }
16 private static int exprCount;
17 }
18
19 [nodiscard]
20 public Result<UniquePtr<Expr>> ParseXPathExpr(const string& xpathExpr)
21 {
22 auto utf32Result = ToUtf32(xpathExpr);
23 if (utf32Result.Error())
24 {
25 return Result<UniquePtr<Expr>>(ErrorId(utf32Result.GetErrorId()));
26 }
27 const ustring& xpathExprString = utf32Result.Value();
28 int exprCount = ExprCounter.GetExprCount();
29 XPathLexer lexer(xpathExprString.Chars(), xpathExprString.Chars() + xpathExprString.Length(), "xpath_expression_" + ToString(exprCount));
30 lexer.SetFileIndex(exprCount);
31 System.Lex.XmlParsingLog log(Console.Error());
32 if (System.XPath.DebugParse())
33 {
34 lexer.SetLog(&log);
35 }
36 Result<UniquePtr<Expr>> exprResult = XPathParser<XPathLexer>.Parse(lexer);
37 if (exprResult.Error())
38 {
39 return exprResult;
40 }
41 if (System.XPath.Debug())
42 {
43 Expr* expr = exprResult.Value().Get();
44 System.Xml.Document exprDoc;
45 exprDoc.AppendChild(expr->ToXmlElement());
46 System.Text.CodeFormatter formatter(Console.Error());
47 formatter.SetIndentSize(1);
48 auto result = exprDoc.Write(formatter);
49 if (result.Error())
50 {
51 return Result<UniquePtr<Expr>>(ErrorId(result.GetErrorId()));
52 }
53 }
54 return exprResult;
55 }
56
57 [nodiscard]
58 public Result<UniquePtr<Object>> Evaluate(Expr* expr, System.Xml.Node* node)
59 {
60 Context context(node, 1, 1);
61 auto result = expr->Evaluate(context);
62 if (result.Error())
63 {
64 return result;
65 }
66 if (System.XPath.Debug())
67 {
68 System.Xml.Document resultDoc;
69 resultDoc.AppendChild(result.Value()->ToXmlElement());
70 System.Text.CodeFormatter formatter(Console.Error());
71 formatter.SetIndentSize(1);
72 auto writeResult = resultDoc.Write(formatter);
73 if (writeResult.Error())
74 {
75 return Result<UniquePtr<Object>>(ErrorId(writeResult.GetErrorId()));
76 }
77 }
78 return result;
79 }
80
81 [nodiscard]
82 public Result<UniquePtr<Object>> Evaluate(const string& xpathExpr, System.Xml.Node* node)
83 {
84 Result<UniquePtr<Expr>> exprResult = ParseXPathExpr(xpathExpr);
85 if (exprResult.Error())
86 {
87 return Result<UniquePtr<Object>>(ErrorId(exprResult.GetErrorId()));
88 }
89 Expr* expr = exprResult.Value().Get();
90 return Evaluate(expr, node);
91 }
92
93 [nodiscard]
94 public Result<UniquePtr<NodeSet>> EvaluateToNodeSet(Expr* expr, System.Xml.Node* node)
95 {
96 Result<UniquePtr<Object>> result = Evaluate(expr, node);
97 if (result.Error())
98 {
99 return Result<UniquePtr<NodeSet>>(ErrorId(result.GetErrorId()));
100 }
101 if (result.Value()->IsNodeSet())
102 {
103 return Result<UniquePtr<NodeSet>>(UniquePtr<NodeSet>(cast<NodeSet*>(result.Value().Release())));
104 }
105 else
106 {
107 int errorId = AllocateError("node-set expected");
108 return Result<UniquePtr<NodeSet>>(ErrorId(errorId));
109 }
110 }
111
112 [nodiscard]
113 public Result<UniquePtr<NodeSet>> EvaluateToNodeSet(const string& xpathExpr, System.Xml.Node* node)
114 {
115 Result<UniquePtr<Expr>> exprResult = ParseXPathExpr(xpathExpr);
116 if (exprResult.Error())
117 {
118 return Result<UniquePtr<NodeSet>>(ErrorId(exprResult.GetErrorId()));
119 }
120 Expr* expr = exprResult.Value().Get();
121 return EvaluateToNodeSet(expr, node);
122 }