1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/*
2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle
3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2005, Google Inc.
4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without
6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met:
7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  1. Redistributions of source code must retain the above copyright notice,
9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer.
10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  2. Redistributions in binary form must reproduce the above copyright notice,
11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer in the documentation
12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     and/or other materials provided with the distribution.
13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  3. The name of the author may not be used to endorse or promote products
14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     derived from this software without specific prior written permission.
15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */
27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <string>
29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <iostream>
30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <vector>
31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <sstream>
32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/common.h"
34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmllite/xmlelement.h"
35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmllite/qname.h"
36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmllite/xmlparser.h"
37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmllite/xmlbuilder.h"
38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmllite/xmlprinter.h"
39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmllite/xmlconstants.h"
40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace buzz {
42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst QName QN_EMPTY(true, STR_EMPTY, STR_EMPTY);
44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst QName QN_XMLNS(true, STR_EMPTY, STR_XMLNS);
45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlChild::~XmlChild() {
48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool
51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlText::IsTextImpl() const {
52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return true;
53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement *
56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlText::AsElementImpl() const {
57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return NULL;
58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlText *
61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlText::AsTextImpl() const {
62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return const_cast<XmlText *>(this);
63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlText::SetText(const std::string & text) {
67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  text_ = text;
68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlText::AddParsedText(const char * buf, int len) {
72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  text_.append(buf, len);
73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlText::AddText(const std::string & text) {
77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  text_ += text;
78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlText::~XmlText() {
81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::XmlElement(const QName & name) :
84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    name_(name),
85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pFirstAttr_(NULL),
86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastAttr_(NULL),
87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pFirstChild_(NULL),
88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastChild_(NULL),
89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    cdata_(false) {
90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::XmlElement(const XmlElement & elt) :
93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    XmlChild(),
94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    name_(elt.name_),
95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pFirstAttr_(NULL),
96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastAttr_(NULL),
97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pFirstChild_(NULL),
98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastChild_(NULL),
99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    cdata_(false) {
100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // copy attributes
102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr * pAttr;
103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr ** ppLastAttr = &pFirstAttr_;
104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr * newAttr = NULL;
105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pAttr = elt.pFirstAttr_; pAttr; pAttr = pAttr->NextAttr()) {
106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    newAttr = new XmlAttr(*pAttr);
107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    *ppLastAttr = newAttr;
108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    ppLastAttr = &(newAttr->pNextAttr_);
109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pLastAttr_ = newAttr;
111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // copy children
113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pChild;
114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild ** ppLast = &pFirstChild_;
115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * newChild = NULL;
116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pChild = elt.pFirstChild_; pChild; pChild = pChild->NextChild()) {
118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (pChild->IsText()) {
119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      newChild = new XmlText(*(pChild->AsText()));
120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    } else {
121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      newChild = new XmlElement(*(pChild->AsElement()));
122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    *ppLast = newChild;
124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    ppLast = &(newChild->pNextChild_);
125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pLastChild_ = newChild;
127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  cdata_ = elt.cdata_;
129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::XmlElement(const QName & name, bool useDefaultNs) :
132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  name_(name),
133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pFirstAttr_(useDefaultNs ? new XmlAttr(QN_XMLNS, name.Namespace()) : NULL),
134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pLastAttr_(pFirstAttr_),
135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pFirstChild_(NULL),
136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pLastChild_(NULL),
137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  cdata_(false) {
138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool
141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::IsTextImpl() const {
142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return false;
143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement *
146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::AsElementImpl() const {
147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return const_cast<XmlElement *>(this);
148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlText *
151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::AsTextImpl() const {
152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return NULL;
153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string &
156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::BodyText() const {
157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (pFirstChild_ && pFirstChild_->IsText() && pLastChild_ == pFirstChild_) {
158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return pFirstChild_->AsText()->Text();
159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return STR_EMPTY;
162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::SetBodyText(const std::string & text) {
166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (text == STR_EMPTY) {
167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    ClearChildren();
168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  } else if (pFirstChild_ == NULL) {
169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    AddText(text);
170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  } else if (pFirstChild_->IsText() && pLastChild_ == pFirstChild_) {
171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pFirstChild_->AsText()->SetText(text);
172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  } else {
173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    ClearChildren();
174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    AddText(text);
175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst QName &
179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::FirstElementName() const {
180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const XmlElement * element = FirstElement();
181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (element == NULL)
182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return QN_EMPTY;
183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return element->Name();
184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlAttr *
187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::FirstAttr() {
188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return pFirstAttr_;
189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string &
192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::Attr(const QName & name) const {
193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr * pattr;
194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (pattr->name_ == name)
196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return pattr->value_;
197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return STR_EMPTY;
199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool
202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::HasAttr(const QName & name) const {
203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr * pattr;
204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (pattr->name_ == name)
206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return true;
207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return false;
209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::SetAttr(const QName & name, const std::string & value) {
213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr * pattr;
214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (pattr->name_ == name)
216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!pattr) {
219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pattr = new XmlAttr(name, value);
220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (pLastAttr_)
221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      pLastAttr_->pNextAttr_ = pattr;
222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    else
223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      pFirstAttr_ = pattr;
224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastAttr_ = pattr;
225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pattr->value_ = value;
228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::ClearAttr(const QName & name) {
232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr * pattr;
233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr *pLastAttr = NULL;
234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (pattr->name_ == name)
236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastAttr = pattr;
238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!pattr)
240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!pLastAttr)
242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pFirstAttr_ = pattr->pNextAttr_;
243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  else
244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastAttr->pNextAttr_ = pattr->pNextAttr_;
245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (pLastAttr_ == pattr)
246f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastAttr_ = pLastAttr;
247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  delete pattr;
248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlChild *
251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::FirstChild() {
252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return pFirstChild_;
253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement *
256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::FirstElement() {
257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pChild;
258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (!pChild->IsText())
260f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return pChild->AsElement();
261f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
262f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return NULL;
263f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement *
266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::NextElement() {
267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pChild;
268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (!pChild->IsText())
270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return pChild->AsElement();
271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return NULL;
273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement *
276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::FirstWithNamespace(const std::string & ns) {
277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pChild;
278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns)
280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return pChild->AsElement();
281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return NULL;
283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
284f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
285f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement *
286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::NextWithNamespace(const std::string & ns) {
287f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pChild;
288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
289f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns)
290f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return pChild->AsElement();
291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return NULL;
293f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
294f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
295f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement *
296f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::FirstNamed(const QName & name) {
297f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pChild;
298f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
299f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
300f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return pChild->AsElement();
301f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
302f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return NULL;
303f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
304f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
305f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement *
306f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::NextNamed(const QName & name) {
307f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pChild;
308f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
309f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
310f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return pChild->AsElement();
311f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
312f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return NULL;
313f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
314f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
315f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement* XmlElement::FindOrAddNamedChild(const QName& name) {
316f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlElement* child = FirstNamed(name);
317f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!child) {
318f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    child = new XmlElement(name);
319f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    AddElement(child);
320f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
321f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
322f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return child;
323f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
324f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
325f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string &
326f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::TextNamed(const QName & name) const {
327f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pChild;
328f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
329f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (!pChild->IsText() && pChild->AsElement()->Name() == name)
330f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      return pChild->AsElement()->BodyText();
331f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
332f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return STR_EMPTY;
333f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
334f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
335f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
336f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::InsertChildAfter(XmlChild * pPredecessor, XmlChild * pNext) {
337f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (pPredecessor == NULL) {
338f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pNext->pNextChild_ = pFirstChild_;
339f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pFirstChild_ = pNext;
340f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
341f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  else {
342f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pNext->pNextChild_ = pPredecessor->pNextChild_;
343f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pPredecessor->pNextChild_ = pNext;
344f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
345f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
346f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
347f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
348f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::RemoveChildAfter(XmlChild * pPredecessor) {
349f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pNext;
350f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
351f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (pPredecessor == NULL) {
352f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pNext = pFirstChild_;
353f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pFirstChild_ = pNext->pNextChild_;
354f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
355f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  else {
356f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pNext = pPredecessor->pNextChild_;
357f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pPredecessor->pNextChild_ = pNext->pNextChild_;
358f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
359f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
360f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (pLastChild_ == pNext)
361f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastChild_ = pPredecessor;
362f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
363f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  delete pNext;
364f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
365f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
366f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
367f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::AddAttr(const QName & name, const std::string & value) {
368f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(!HasAttr(name));
369f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
370f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr ** pprev = pLastAttr_ ? &(pLastAttr_->pNextAttr_) : &pFirstAttr_;
371f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pLastAttr_ = (*pprev = new XmlAttr(name, value));
372f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
373f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
374f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
375f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::AddAttr(const QName & name, const std::string & value,
376f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                         int depth) {
377f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlElement * element = this;
378f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  while (depth--) {
379f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    element = element->pLastChild_->AsElement();
380f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
381f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  element->AddAttr(name, value);
382f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
383f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
384f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
385f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::AddParsedText(const char * cstr, int len) {
386f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (len == 0)
387f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
388f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
389f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (pLastChild_ && pLastChild_->IsText()) {
390f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastChild_->AsText()->AddParsedText(cstr, len);
391f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
392f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
393f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
394f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pLastChild_ = *pprev = new XmlText(cstr, len);
395f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
396f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
397f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
398f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::AddCDATAText(const char * buf, int len) {
399f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  cdata_ = true;
400f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  AddParsedText(buf, len);
401f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
402f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
403f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
404f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::AddText(const std::string & text) {
405f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (text == STR_EMPTY)
406f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
407f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
408f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (pLastChild_ && pLastChild_->IsText()) {
409f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pLastChild_->AsText()->AddText(text);
410f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
411f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
412f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
413f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pLastChild_ = *pprev = new XmlText(text);
414f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
415f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
416f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
417f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::AddText(const std::string & text, int depth) {
418f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // note: the first syntax is ambigious for msvc 6
419f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // XmlElement * pel(this);
420f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlElement * element = this;
421f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  while (depth--) {
422f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    element = element->pLastChild_->AsElement();
423f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
424f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  element->AddText(text);
425f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
426f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
427f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
428f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::AddElement(XmlElement *pelChild) {
429f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (pelChild == NULL)
430f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
431f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
432f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
433f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pLastChild_ = *pprev = pelChild;
434f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pelChild->pNextChild_ = NULL;
435f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
436f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
437f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
438f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::AddElement(XmlElement *pelChild, int depth) {
439f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlElement * element = this;
440f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  while (depth--) {
441f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    element = element->pLastChild_->AsElement();
442f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
443f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  element->AddElement(pelChild);
444f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
445f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
446f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
447f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::ClearNamedChildren(const QName & name) {
448f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * prev_child = NULL;
449f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * next_child;
450f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * child;
451f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (child = FirstChild(); child; child = next_child) {
452f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    next_child = child->NextChild();
453f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (!child->IsText() && child->AsElement()->Name() == name)
454f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    {
455f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      RemoveChildAfter(prev_child);
456f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      continue;
457f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
458f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    prev_child = child;
459f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
460f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
461f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
462f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
463f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::ClearAttributes() {
464f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr * pattr;
465f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pattr = pFirstAttr_; pattr; ) {
466f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    XmlAttr * pToDelete = pattr;
467f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pattr = pattr->pNextAttr_;
468f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    delete pToDelete;
469f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
470f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pFirstAttr_ = pLastAttr_ = NULL;
471f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
472f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
473f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
474f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::ClearChildren() {
475f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pchild;
476f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pchild = pFirstChild_; pchild; ) {
477f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    XmlChild * pToDelete = pchild;
478f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pchild = pchild->pNextChild_;
479f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    delete pToDelete;
480f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
481f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pFirstChild_ = pLastChild_ = NULL;
482f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
483f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
484f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstd::string
485f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::Str() const {
486f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::stringstream ss;
487f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Print(&ss, NULL, 0);
488f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ss.str();
489f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
490f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
491f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement *
492f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::ForStr(const std::string & str) {
493f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlBuilder builder;
494f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlParser::ParseXml(&builder, str);
495f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return builder.CreateElement();
496f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
497f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
498f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid
499f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::Print(
500f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    std::ostream * pout, std::string xmlns[], int xmlnsCount) const {
501f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlPrinter::PrintXml(pout, this, xmlns, xmlnsCount);
502f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
503f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
504f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochXmlElement::~XmlElement() {
505f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlAttr * pattr;
506f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pattr = pFirstAttr_; pattr; ) {
507f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    XmlAttr * pToDelete = pattr;
508f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pattr = pattr->pNextAttr_;
509f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    delete pToDelete;
510f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
511f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
512f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmlChild * pchild;
513f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (pchild = pFirstChild_; pchild; ) {
514f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    XmlChild * pToDelete = pchild;
515f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pchild = pchild->pNextChild_;
516f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    delete pToDelete;
517f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
518f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
519f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
520f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
521