1
2
3
4
5
6 using System;
7 using System.Xml;
8
9 namespace System.XPath
10 {
11 public enum NodeTestKind
12 {
13 piLiteralTest, commentNodeTest, textNodeTest, piNodeTest, anyNodeTest, principalNodeTest, prefixTest, nameTest
14 }
15
16 public string NodeTestStr(NodeTestKind kind)
17 {
18 switch (kind)
19 {
20 case NodeTestKind.piLiteralTest: return "pi-literal-test";
21 case NodeTestKind.commentNodeTest: return "comment-node-test";
22 case NodeTestKind.textNodeTest: return "text-node-test";
23 case NodeTestKind.piNodeTest: return "pi-node-test";
24 case NodeTestKind.anyNodeTest: return "any-node-test";
25 case NodeTestKind.principalNodeTest: return "principal-node-test";
26 case NodeTestKind.prefixTest: return "prefix-node-test";
27 case NodeTestKind.nameTest: return "name-node-test";
28 }
29 return "<unknown node-test>";
30 }
31
32 public class NodeTest
33 {
34 public NodeTest(NodeTestKind kind_) : kind(kind_)
35 {
36 }
37 public inline NodeTestKind Kind() const
38 {
39 return kind;
40 }
41 public virtual default ~NodeTest();
42 public virtual bool Select(System.Xml.Node* node, System.Xml.Axis axis) const
43 {
44 switch (kind)
45 {
46 case NodeTestKind.commentNodeTest:
47 {
48 return node->IsCommentNode();
49 }
50 case NodeTestKind.textNodeTest:
51 {
52 return node->IsTextNode();
53 }
54 case NodeTestKind.piNodeTest:
55 {
56 return node->IsProcessingInstructionNode();
57 }
58 case NodeTestKind.anyNodeTest:
59 {
60 return true;
61 }
62 case NodeTestKind.principalNodeTest:
63 {
64 if (axis == System.Xml.Axis.attribute)
65 {
66 return node->IsAttributeNode();
67 }
68 else if (axis == System.Xml.Axis.ns)
69 {
70 #assert(false);
71 }
72 else
73 {
74 return node->IsElementNode();
75 }
76 break;
77 }
78 }
79 return false;
80 }
81 public virtual System.Xml.Element* ToXmlElement() const
82 {
83 System.Xml.Element* element = System.Xml.MakeElement("node-test");
84 element->SetAttribute("kind", NodeTestStr(kind));
85 return element;
86 }
87 private NodeTestKind kind;
88 }
89
90 public class PILiteralNodeTest : NodeTest
91 {
92 public explicit PILiteralNodeTest(Literal* literal_) : base(NodeTestKind.piLiteralTest), literal(literal_)
93 {
94 }
95 public inline Literal* GetLiteral() const
96 {
97 return literal.Get();
98 }
99 public override bool Select(System.Xml.Node* node, System.Xml.Axis axis) const
100 {
101 if (node->IsProcessingInstructionNode())
102 {
103 System.Xml.ProcessingInstruction* pi = cast<System.Xml.ProcessingInstruction*>(node);
104 if (pi->Target() == literal->Value())
105 {
106 return true;
107 }
108 }
109 return false;
110 }
111 public override System.Xml.Element* ToXmlElement() const
112 {
113 System.Xml.Element* element = base->ToXmlElement();
114 element->AppendChild(literal->ToXmlElement());
115 return element;
116 }
117 private UniquePtr<Literal> literal;
118 }
119
120 public class PrefixNodeTest : NodeTest
121 {
122 public PrefixNodeTest(const string& prefix_) : base(NodeTestKind.prefixTest), prefix(prefix_)
123 {
124 }
125 public override bool Select(System.Xml.Node* node, System.Xml.Axis axis) const
126 {
127 if (axis == System.Xml.Axis.attribute)
128 {
129 if (node->IsAttributeNode())
130 {
131 if (node->Prefix() == prefix)
132 {
133 return true;
134 }
135 }
136 }
137 else if (axis == System.Xml.Axis.ns)
138 {
139 #assert(false);
140 }
141 else if (node->IsElementNode())
142 {
143 if (node->Prefix() == prefix)
144 {
145 return true;
146 }
147 }
148 return false;
149 }
150 public override System.Xml.Element* ToXmlElement() const
151 {
152 System.Xml.Element* element = base->ToXmlElement();
153 element->SetAttribute("prefix", prefix);
154 return element;
155 }
156 private string prefix;
157 }
158
159 public class NameNodeTest : NodeTest
160 {
161 public NameNodeTest(const string& name_) : base(NodeTestKind.nameTest), name(name_)
162 {
163 }
164 public inline const string& Name() const
165 {
166 return name;
167 }
168 public override bool Select(System.Xml.Node* node, System.Xml.Axis axis) const
169 {
170 if (axis == System.Xml.Axis.attribute)
171 {
172 if (node->IsAttributeNode())
173 {
174 if (node->Name() == name)
175 {
176 return true;
177 }
178 }
179 }
180 else if (axis == System.Xml.Axis.ns)
181 {
182 #assert(false);
183 }
184 else
185 {
186 if (node->IsElementNode())
187 {
188 if (node->Name() == name)
189 {
190 return true;
191 }
192 }
193 }
194 return false;
195 }
196 public override System.Xml.Element* ToXmlElement() const
197 {
198 System.Xml.Element* element = base->ToXmlElement();
199 element->SetAttribute("name", name);
200 return element;
201 }
202 private string name;
203 }
204
205 public class NodeSelectionOperation : System.Xml.NodeOperation
206 {
207 public NodeSelectionOperation(NodeTest* nodeTest_, NodeSet& nodeSet_, System.Xml.Axis axis_) : nodeTest(nodeTest_), nodeSet(nodeSet_), axis(axis_)
208 {
209 }
210 public override void Apply(System.Xml.Node* node)
211 {
212 if (nodeTest->Select(node, axis))
213 {
214 nodeSet.Add(node);
215 }
216 }
217 private NodeTest* nodeTest;
218 private NodeSet& nodeSet;
219 private System.Xml.Axis axis;
220 }