1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef THIRD_PARTY_LIBXML_CHROMIUM_LIBXML_UTILS_H_
6 #define THIRD_PARTY_LIBXML_CHROMIUM_LIBXML_UTILS_H_
11 #include "libxml/xmlreader.h"
12 #include "libxml/xmlwriter.h"
14 // Converts a libxml xmlChar* into a UTF-8 std::string.
15 // NULL inputs produce an empty string.
16 std::string
XmlStringToStdString(const xmlChar
* xmlstring
);
18 // libxml uses a global error function pointer for reporting errors.
19 // A ScopedXmlErrorFunc object lets you change the global error pointer
20 // for the duration of the object's lifetime.
21 class ScopedXmlErrorFunc
{
23 ScopedXmlErrorFunc(void* context
, xmlGenericErrorFunc func
) {
24 old_error_func_
= xmlGenericError
;
25 old_error_context_
= xmlGenericErrorContext
;
26 xmlSetGenericErrorFunc(context
, func
);
28 ~ScopedXmlErrorFunc() {
29 xmlSetGenericErrorFunc(old_error_context_
, old_error_func_
);
33 xmlGenericErrorFunc old_error_func_
;
34 void* old_error_context_
;
37 // XmlReader is a wrapper class around libxml's xmlReader,
38 // providing a simplified C++ API.
44 // Load a document into the reader from memory. |input| must be UTF-8 and
45 // exist for the lifetime of this object. Returns false on error.
46 // TODO(evanm): handle encodings other than UTF-8?
47 bool Load(const std::string
& input
);
49 // Load a document into the reader from a file. Returns false on error.
50 bool LoadFile(const std::string
& file_path
);
52 // Wrappers around libxml functions -----------------------------------------
54 // Read() advances to the next node. Returns false on EOF or error.
55 bool Read() { return xmlTextReaderRead(reader_
) == 1; }
57 // Next(), when pointing at an opening tag, advances to the node after
58 // the matching closing tag. Returns false on EOF or error.
59 bool Next() { return xmlTextReaderNext(reader_
) == 1; }
61 // Return the depth in the tree of the current node.
62 int Depth() { return xmlTextReaderDepth(reader_
); }
64 // Returns the "local" name of the current node.
65 // For a tag like <foo:bar>, this is the string "foo:bar".
66 std::string
NodeName() {
67 return XmlStringToStdString(xmlTextReaderConstLocalName(reader_
));
70 // When pointing at a tag, retrieves the value of an attribute.
71 // Returns false on failure.
72 // E.g. for <foo bar:baz="a">, NodeAttribute("bar:baz", &value)
73 // returns true and |value| is set to "a".
74 bool NodeAttribute(const char* name
, std::string
* value
);
76 // Returns true if the node is a closing element (e.g. </foo>).
77 bool IsClosingElement();
79 // Helper functions not provided by libxml ----------------------------------
81 // Return the string content within an element.
82 // "<foo>bar</foo>" is a sequence of three nodes:
83 // (1) open tag, (2) text, (3) close tag.
84 // With the reader currently at (1), this returns the text of (2),
85 // and advances past (3).
86 // Returns false on error.
87 bool ReadElementContent(std::string
* content
);
89 // Skip to the next opening tag, returning false if we reach a closing
91 // If currently on an opening tag, doesn't advance at all.
95 // Returns the libxml node type of the current node.
96 int NodeType() { return xmlTextReaderNodeType(reader_
); }
98 // The underlying libxml xmlTextReader.
99 xmlTextReaderPtr reader_
;
102 // XmlWriter is a wrapper class around libxml's xmlWriter,
103 // providing a simplified C++ API.
104 // StartWriting must be called before other methods, and StopWriting
105 // must be called before GetWrittenString() will return results.
111 // Allocates the xmlTextWriter and an xmlBuffer and starts an XML document.
112 // This must be called before any other functions. By default, indenting is
116 // Ends the XML document and frees the xmlTextWriter.
117 // This must be called before GetWrittenString() is called.
119 // Wrappers around libxml functions -----------------------------------------
121 // All following elements will be indented to match their depth.
122 void StartIndenting() { xmlTextWriterSetIndent(writer_
, 1); }
124 // All follow elements will not be indented.
125 void StopIndenting() { xmlTextWriterSetIndent(writer_
, 0); }
127 // Start an element with the given name. All future elements added will be
128 // children of this element, until it is ended. Returns false on error.
129 bool StartElement(const std::string
& element_name
) {
130 return xmlTextWriterStartElement(writer_
,
131 BAD_CAST element_name
.c_str()) >= 0;
134 // Ends the current open element. Returns false on error.
136 return xmlTextWriterEndElement(writer_
) >= 0;
139 // Appends to the content of the current open element.
140 bool AppendElementContent(const std::string
& content
) {
141 return xmlTextWriterWriteString(writer_
,
142 BAD_CAST content
.c_str()) >= 0;
145 // Adds an attribute to the current open element. Returns false on error.
146 bool AddAttribute(const std::string
& attribute_name
,
147 const std::string
& attribute_value
) {
148 return xmlTextWriterWriteAttribute(writer_
,
149 BAD_CAST attribute_name
.c_str(),
150 BAD_CAST attribute_value
.c_str()) >= 0;
153 // Adds a new element with name |element_name| and content |content|
154 // to the buffer. Example: <|element_name|>|content|</|element_name|>
155 // Returns false on errors.
156 bool WriteElement(const std::string
& element_name
,
157 const std::string
& content
) {
158 return xmlTextWriterWriteElement(writer_
,
159 BAD_CAST element_name
.c_str(),
160 BAD_CAST content
.c_str()) >= 0;
163 // Helper functions not provided by xmlTextWriter ---------------------------
165 // Returns the string that has been written to the buffer.
166 std::string
GetWrittenString() {
169 return XmlStringToStdString(buffer_
->content
);
173 // The underlying libxml xmlTextWriter.
174 xmlTextWriterPtr writer_
;
176 // Stores the output.
177 xmlBufferPtr buffer_
;
180 #endif // THIRD_PARTY_LIBXML_CHROMIUM_INCLUDE_LIBXML_LIBXML_UTILS_H_