1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // MDXMLElement.CPP |
|
15 // @file |
|
16 // This file contains the implementation of the CMDXMLElement class. |
|
17 // This class represents a generic XML element with attributes |
|
18 // stored as name-value pairs. DTD-specific element classes |
|
19 // will store their attributes as member variables. |
|
20 // |
|
21 // |
|
22 |
|
23 #include <f32file.h> |
|
24 |
|
25 #include <gmxmldomconstants.h> |
|
26 #include <gmxmlnode.h> |
|
27 #include <gmxmldocument.h> |
|
28 #include <gmxmlelement.h> |
|
29 |
|
30 |
|
31 EXPORT_C CMDXMLElement* CMDXMLElement::NewLC( TBool aCanHaveChildren, CMDXMLDocument* aOwnerDocument, TPtrC aTagName ) |
|
32 // |
|
33 // Two phase constructor |
|
34 // @param aCanHaveChildren Flag to indicate if the node represents a node |
|
35 // @param aOwnerDocument Pointer to the document at the root of the DOM tree |
|
36 // @param aTagName Name of the tag used to create the element |
|
37 // @return Created CMDXMLElement |
|
38 // @leave can Leave due to OOM |
|
39 // |
|
40 { |
|
41 CMDXMLElement* elPtr = new(ELeave) CMDXMLElement( aCanHaveChildren, aOwnerDocument ); |
|
42 CleanupStack::PushL( elPtr ); |
|
43 elPtr->SetNodeNameL( aTagName ); |
|
44 elPtr->ConstructL(); |
|
45 return elPtr; |
|
46 } |
|
47 |
|
48 EXPORT_C CMDXMLElement* CMDXMLElement::NewL( TBool aCanHaveChildren, CMDXMLDocument* aOwnerDocument, TPtrC aTagName ) |
|
49 // |
|
50 // Two phase constructor |
|
51 // @param aCanHaveChildren Flag to indicate if the node represents a node |
|
52 // @param aOwnerDocument Pointer to the document at the root of the DOM tree |
|
53 // @param aTagName Name of the tag used to create the element |
|
54 // @return Created CMDXMLElement |
|
55 // @leave can Leave due to OOM |
|
56 // |
|
57 { |
|
58 CMDXMLElement* elPtr = CMDXMLElement::NewLC( aCanHaveChildren, aOwnerDocument, aTagName ); |
|
59 CleanupStack::Pop(elPtr); |
|
60 return elPtr; |
|
61 } |
|
62 |
|
63 EXPORT_C CMDXMLElement::CMDXMLElement( TBool aCanHaveChildren, CMDXMLDocument* aOwnerDocument ): |
|
64 CMDXMLNode( EElementNode, aCanHaveChildren, aOwnerDocument) |
|
65 // |
|
66 // Constructor |
|
67 // @param aCanHaveChildren Flag to indicate if the node represents a node which is allowed children |
|
68 // @param aOwnerDocument Pointer to the document at the root of the DOM tree |
|
69 // |
|
70 { |
|
71 // No other work to do. |
|
72 } |
|
73 |
|
74 void CMDXMLElement::ConstructL() |
|
75 /** |
|
76 * 2nd-phase constructor. Initialises this object's member data. |
|
77 * |
|
78 * @leave KErrXxx Standard EPOC error codes if allocation or construction of the object's members fails |
|
79 */ |
|
80 { |
|
81 iDescAttName = new (ELeave) CDesCArraySeg(1); |
|
82 iDescAttValue = new (ELeave) CDesCArraySeg(1); |
|
83 |
|
84 } |
|
85 |
|
86 EXPORT_C CMDXMLElement::~CMDXMLElement() |
|
87 /** |
|
88 * C++ destructor |
|
89 */ |
|
90 { |
|
91 // Delete the array of attribute name-value pairs. |
|
92 if(iDescAttName) |
|
93 delete iDescAttName; |
|
94 |
|
95 if(iDescAttValue) |
|
96 delete iDescAttValue; |
|
97 |
|
98 } |
|
99 |
|
100 |
|
101 EXPORT_C TInt CMDXMLElement::GetAttribute(const TDesC& aAttributeName, TPtrC& aAttributeValue) const |
|
102 // |
|
103 // Returns the attribute value if it is set. |
|
104 // @param aAttributeName Name of attribute to return |
|
105 // @param aAttributeValue Value of attribute returned |
|
106 // @return Returns KErrNone if successful, KErrNotFound if the named attribute |
|
107 // is not set or KErrNotSupported if the named attribute doesn't exist. |
|
108 // |
|
109 { |
|
110 TInt returnValue = KErrNone; |
|
111 |
|
112 TInt index; |
|
113 TInt attributeFound; |
|
114 attributeFound = iDescAttName->Find(aAttributeName,index); |
|
115 |
|
116 if(attributeFound == 0) |
|
117 { |
|
118 aAttributeValue.Set(iDescAttValue->MdcaPoint(index)); |
|
119 } |
|
120 else |
|
121 returnValue = KErrNotSupported; |
|
122 |
|
123 return returnValue; |
|
124 |
|
125 } |
|
126 |
|
127 EXPORT_C TInt CMDXMLElement::SetAttributeL(const TDesC& aAttributeName, const TDesC& aAttributeValue) |
|
128 // |
|
129 // Sets the attribute value.if it is valid |
|
130 // @param aAttributeName Name of attribute to set |
|
131 // @param aAttributeValue Value of attribute |
|
132 // @return Returns KErrNone if successful, KErrNotSupported if a DTD-specific class. |
|
133 // @leave Can Leave due to OOM |
|
134 // |
|
135 { |
|
136 return SetAttributeL(aAttributeName, aAttributeValue, EFalse); |
|
137 } |
|
138 |
|
139 EXPORT_C TInt CMDXMLElement::SetAttributeL(const TDesC& aAttributeName, const TDesC& aAttributeValue, TBool aStoreInvalid) |
|
140 // |
|
141 // Checks an attribute for validity and adds it to the DOM. The aStoreInvalid parameter is used to control whether invalid |
|
142 // attributes are added to the DOM. |
|
143 // @param aAttributeName Name of attribute to set |
|
144 // @param aAttributeValue Value of attribute |
|
145 // @param aStoreInvalid If set to ETrue all attributes will be stored in the DOM. Otherwise only those that are valid will be. |
|
146 // @return Returns KErrNone if successful, KErrNotSupported if a DTD-specific class. |
|
147 // @leave Can Leave due to OOM |
|
148 // |
|
149 { |
|
150 TInt returnValue = (iOwnerDocument->DtdRepresentation()).IsValidAttributeForElementL(NodeName(), aAttributeName, aAttributeValue); |
|
151 |
|
152 if(returnValue == KErrNone || aStoreInvalid) |
|
153 { |
|
154 iDescAttName->AppendL(aAttributeName); |
|
155 iDescAttValue->AppendL(aAttributeValue); |
|
156 } |
|
157 |
|
158 return returnValue; |
|
159 } |
|
160 |
|
161 EXPORT_C TInt CMDXMLElement::RemoveAttribute(const TDesC& aAttributeName) |
|
162 // |
|
163 // Removes the named attribute if present. |
|
164 // @param aAttributeName Name of attribute to set |
|
165 // @return Returns KErrNone if successful, KErrNotFound if the named attribute is not set, KErrNotSupported if a DTD-specific class. |
|
166 // |
|
167 { |
|
168 TInt returnValue = KErrNone; |
|
169 |
|
170 TInt index; |
|
171 TInt attributeFound; |
|
172 attributeFound = iDescAttName->Find(aAttributeName,index); |
|
173 |
|
174 if(attributeFound == 0) |
|
175 { |
|
176 iDescAttName->Delete(index); |
|
177 iDescAttValue->Delete(index); |
|
178 } |
|
179 else |
|
180 returnValue = KErrNotFound; |
|
181 |
|
182 return returnValue; |
|
183 } |
|
184 |
|
185 |
|
186 EXPORT_C TBool CMDXMLElement::IsAttributeSpecified(const TDesC& aAttributeName) const |
|
187 // |
|
188 // Finds out whether or not the named attribute is set |
|
189 // @param aAttributeName Name of attribute that is subject of the enquiry. |
|
190 // @return true of the named attribute has a value set, false if not |
|
191 // |
|
192 { |
|
193 TBool returnValue = EFalse; |
|
194 |
|
195 if(iDescAttName) |
|
196 { |
|
197 TInt index = 0; |
|
198 TInt found = 0; |
|
199 found = iDescAttName->Find(aAttributeName,index); |
|
200 if(found == 0) |
|
201 returnValue = ETrue; |
|
202 } |
|
203 |
|
204 return returnValue; |
|
205 } |
|
206 |
|
207 |
|
208 |
|
209 |
|
210 |
|
211 EXPORT_C TBool CMDXMLElement::CheckImmediateChildren() |
|
212 // Check the immediate children of this element - i.e. the first level of children only |
|
213 // If the document has not been constructed with a pointer to a MXMLDtd object then a default ETrue will be returned |
|
214 // Otherwise the MXMLDtd object is used to validate immediate children - returns ETrue if valid |
|
215 // @return True if immediate children are valid |
|
216 { |
|
217 TBool returnValue = ETrue; |
|
218 TRAPD(error,returnValue = DoCheckImmediateChildrenL()); |
|
219 if(error != KErrNone) |
|
220 { |
|
221 return EFalse; |
|
222 } |
|
223 return returnValue; |
|
224 } |
|
225 |
|
226 TBool CMDXMLElement::DoCheckImmediateChildrenL() |
|
227 { |
|
228 TBool returnValue = ETrue; |
|
229 |
|
230 // Create an array of this elements immediate children |
|
231 CDesCArray* children = new (ELeave) CDesCArrayFlat(3); |
|
232 CleanupStack::PushL(children); |
|
233 |
|
234 if (HasChildNodes()) |
|
235 { |
|
236 CMDXMLNode* childPtr; |
|
237 childPtr = FirstChild(); |
|
238 // Cycle through the siblings |
|
239 while (childPtr != NULL) |
|
240 { |
|
241 if( childPtr->NodeType() == EElementNode ) |
|
242 children->AppendL(childPtr->NodeName()); |
|
243 childPtr = childPtr->NextSibling(); |
|
244 } |
|
245 returnValue = OwnerDocument()->DtdRepresentation().AreValidChildElementsL(this->NodeName(),*children); |
|
246 } |
|
247 |
|
248 // Do a DTD specific check to see if the children are valid |
|
249 CleanupStack::PopAndDestroy(); // children |
|
250 |
|
251 return returnValue; |
|
252 } |
|
253 |
|
254 EXPORT_C TBool CMDXMLElement::CheckChildren() |
|
255 // |
|
256 // Check the children of this node for legality - must be defined based on DTD. |
|
257 // This function checks that the list of child elements |
|
258 // conforms to those allowed by the DTD. |
|
259 // As well as checking the list of direct children, it |
|
260 // calls CheckChildren for each child element which is an |
|
261 // element (it does not call this for child nodes which are |
|
262 // not elements as they cannot have children). |
|
263 // @return True if the node has legitimate children |
|
264 // |
|
265 { |
|
266 TBool retVal= CheckImmediateChildren(); |
|
267 if( retVal && HasChildNodes() ) |
|
268 { |
|
269 CMDXMLNode* childPtr; |
|
270 childPtr = FirstChild(); |
|
271 while((childPtr != NULL) && (retVal != false)) |
|
272 { |
|
273 if( childPtr->NodeType() == EElementNode ) |
|
274 { |
|
275 retVal = childPtr->CheckChildren(); |
|
276 } |
|
277 childPtr = childPtr->NextSibling(); |
|
278 } |
|
279 } |
|
280 |
|
281 return retVal; |
|
282 } |
|
283 |
|
284 |
|
285 EXPORT_C TInt CMDXMLElement::FindIndex(const TDesC &aAttName) |
|
286 // |
|
287 // Find an attribute and return the index of it |
|
288 // @param aAttName the string to search for |
|
289 // @return returns the index of the string if found or KErrNotFound |
|
290 // |
|
291 { |
|
292 TInt index = KErrNotFound; |
|
293 |
|
294 if(iDescAttName) |
|
295 { |
|
296 TInt found = 0; |
|
297 found = iDescAttName->Find(aAttName,index); |
|
298 if(found != 0) |
|
299 index = KErrNotFound; |
|
300 } |
|
301 |
|
302 return index; |
|
303 |
|
304 |
|
305 } |
|
306 |
|
307 |
|
308 EXPORT_C TInt CMDXMLElement::AttributeDetails(TInt aIndex, TPtrC& aAttributeName, TPtrC& aAttributeValue) |
|
309 // |
|
310 // Retrieves the Name and Value of an attribute at a given index |
|
311 // @param aIndex the array index of the element for which details are required |
|
312 // @param aAttributeName the attribute name returned |
|
313 // @param aAttributeValue the attribute value returned |
|
314 // @return returns KErrNone if index is valid else KErrNotFound |
|
315 // |
|
316 |
|
317 { |
|
318 TInt error = KErrNone; |
|
319 if (iDescAttName->Count() < aIndex) |
|
320 error = KErrNotFound; |
|
321 else |
|
322 { |
|
323 aAttributeValue.Set(iDescAttValue->MdcaPoint(aIndex)); |
|
324 aAttributeName.Set(iDescAttName->MdcaPoint(aIndex)); |
|
325 } |
|
326 return error; |
|
327 } |
|
328 |
|
329 |
|
330 |
|
331 EXPORT_C TInt CMDXMLElement::NumAttributes() |
|
332 // |
|
333 // Retrieves the Number od Attributes that this element has |
|
334 // @return returns the number of attributes held by the element |
|
335 // |
|
336 { |
|
337 return iDescAttName->Count(); |
|
338 } |
|
339 |
|
340 |
|
341 EXPORT_C CMDXMLElement* CMDXMLElement::FirstChildOfType(const TDesC& aElementType) |
|
342 // @return Returns a pointer to the first child of a given type if any, otherwise returns NULL |
|
343 // @param aElementType Name of element type to return |
|
344 { |
|
345 CMDXMLElement* retVal = NULL; |
|
346 CMDXMLNode* nodePtr = FirstChild(); |
|
347 while((nodePtr != NULL) && (nodePtr->NodeName()).Compare(aElementType) != 0) |
|
348 { |
|
349 nodePtr = nodePtr->NextSibling(); |
|
350 } |
|
351 if( nodePtr != NULL ) |
|
352 { |
|
353 retVal = (CMDXMLElement*)nodePtr; |
|
354 } |
|
355 return retVal; |
|
356 |
|
357 } |
|
358 |
|
359 EXPORT_C CMDXMLElement* CMDXMLElement::LastChildOfType(const TDesC& aElementType) |
|
360 // @return Returns a pointer to the last child of a given type if any, otherwise returns NULL |
|
361 // @param aElementType Name of element type to return |
|
362 |
|
363 { |
|
364 CMDXMLElement* retVal = NULL; |
|
365 CMDXMLNode* nodePtr = LastChild(); |
|
366 while((nodePtr != NULL) && (nodePtr->NodeName()).Compare(aElementType) != 0) |
|
367 { |
|
368 nodePtr = nodePtr->PreviousSibling(); |
|
369 } |
|
370 if( nodePtr != NULL ) |
|
371 { |
|
372 retVal = (CMDXMLElement*)nodePtr; |
|
373 } |
|
374 return retVal; |
|
375 } |
|
376 |
|
377 |
|
378 // End Of File |
|