XmlDom.h revision d5083f6f6b9bc76bbe64052bcec639eee752a321
175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/* 275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Copyright (C) 2015 The Android Open Source Project 375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * 475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * you may not use this file except in compliance with the License. 675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * You may obtain a copy of the License at 775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * 875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * 1075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Unless required by applicable law or agreed to in writing, software 1175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 1275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * See the License for the specific language governing permissions and 1475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * limitations under the License. 1575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 1775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#ifndef AAPT_XML_DOM_H 1875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#define AAPT_XML_DOM_H 1975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 20ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <istream> 21ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <memory> 22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <string> 23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <vector> 24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 25d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#include "androidfw/StringPiece.h" 26d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski 271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Diagnostics.h" 281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Resource.h" 291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "ResourceValues.h" 301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h" 31467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski#include "xml/XmlUtil.h" 3275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 3375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskinamespace aapt { 3475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskinamespace xml { 3575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 365eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass RawVisitor; 3775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 3875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 3975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Base class for all XML nodes. 4075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 415eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Node { 42cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 43cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski Node* parent = nullptr; 44ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_t line_number = 0; 45ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_t column_number = 0; 46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski std::string comment; 47cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski std::vector<std::unique_ptr<Node>> children; 48cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 49cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski virtual ~Node() = default; 50cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 51e343eb145c42d00c4fd3fdde93cd0be55cb5b855Adam Lesinski void AppendChild(std::unique_ptr<Node> child); 52e343eb145c42d00c4fd3fdde93cd0be55cb5b855Adam Lesinski void InsertChild(size_t index, std::unique_ptr<Node> child); 53ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Accept(RawVisitor* visitor) = 0; 54ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual std::unique_ptr<Node> Clone() = 0; 5575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 5675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 5775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 5875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Base class that implements the visitor methods for a 5975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * subclass of Node. 6075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 6175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskitemplate <typename Derived> 625eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass BaseNode : public Node { 63cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 64ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Accept(RawVisitor* visitor) override; 6575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 6675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 6775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 6875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * A Namespace XML node. Can only have one child. 6975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 705eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Namespace : public BaseNode<Namespace> { 71cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 72ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string namespace_prefix; 73ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string namespace_uri; 745eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski 75ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<Node> Clone() override; 761ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 7775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 781ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct AaptAttribute { 79cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski Maybe<ResourceId> id; 80cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski aapt::Attribute attribute; 8175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 8275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 8375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 8475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * An XML attribute. 8575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 8675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Attribute { 87ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string namespace_uri; 88cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski std::string name; 89cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski std::string value; 901ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 91ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Maybe<AaptAttribute> compiled_attribute; 92ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<Item> compiled_value; 9375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 9475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 9575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 9675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * An Element XML node. 9775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 985eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Element : public BaseNode<Element> { 99cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 100ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string namespace_uri; 101cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski std::string name; 102cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski std::vector<Attribute> attributes; 103cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 104d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski Attribute* FindAttribute(const android::StringPiece& ns, const android::StringPiece& name); 105d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski xml::Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name); 106d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski xml::Element* FindChildWithAttribute(const android::StringPiece& ns, 107d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski const android::StringPiece& name, 108d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski const android::StringPiece& attr_ns, 109d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski const android::StringPiece& attr_name, 110d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski const android::StringPiece& attr_value); 111ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::vector<xml::Element*> GetChildElements(); 112ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<Node> Clone() override; 11375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 11475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 11575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 11675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * A Text (CDATA) XML node. Can not have any children. 11775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1185eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Text : public BaseNode<Text> { 119cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 120cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski std::string text; 1215eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski 122ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<Node> Clone() override; 12375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 12475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 12575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 126467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski * An XML resource with a source, name, and XML tree. 127467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski */ 1285eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass XmlResource { 129cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 130cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski ResourceFile file; 131cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski std::unique_ptr<xml::Node> root; 132467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski}; 133467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski 134467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski/** 13575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Inflates an XML DOM from a text stream, logging errors to the logger. 13675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Returns the root node on success, or nullptr on failure. 13775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 138ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskistd::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag, 139cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const Source& source); 14075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 14175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 14275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger. 14375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Returns the root node on success, or nullptr on failure. 14475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 145ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskistd::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len, 146cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski IDiagnostics* diag, const Source& source); 1471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 148ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiElement* FindRootElement(XmlResource* doc); 149ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiElement* FindRootElement(Node* node); 150ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski 1511ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 152cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * A visitor interface for the different XML Node subtypes. This will not 153cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * traverse into 1541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * children. Use Visitor for that. 1551ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 1565eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass RawVisitor { 157cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 158cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski virtual ~RawVisitor() = default; 1591ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 160ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(Namespace* node) {} 161ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(Element* node) {} 162ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski virtual void Visit(Text* text) {} 1631ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 1641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 1661ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Visitor whose default implementation visits the children nodes of any node. 1671ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 1685eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Visitor : public RawVisitor { 169cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 170ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski using RawVisitor::Visit; 1711ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 172ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void Visit(Namespace* node) override { VisitChildren(node); } 1731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 174ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void Visit(Element* node) override { VisitChildren(node); } 1751ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 176ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void Visit(Text* text) override { VisitChildren(text); } 1771ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 178ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void VisitChildren(Node* node) { 179cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski for (auto& child : node->children) { 180ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski child->Accept(this); 1811ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 182cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 1831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 18475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 18575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 1861ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * An XML DOM visitor that will record the package name for a namespace prefix. 18775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1881ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass PackageAwareVisitor : public Visitor, public IPackageDeclStack { 189cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 190ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski using Visitor::Visit; 1915eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski 192ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void Visit(Namespace* ns) override; 193ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Maybe<ExtractedPackage> TransformPackageAlias( 194d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski const android::StringPiece& alias, const android::StringPiece& local_package) const override; 1955eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski 196cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski private: 197cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski struct PackageDecl { 198cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski std::string prefix; 199cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski ExtractedPackage package; 200cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski }; 2011ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 202ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::vector<PackageDecl> package_decls_; 20375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 20475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 20575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski// Implementations 20675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 20775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskitemplate <typename Derived> 208ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskivoid BaseNode<Derived>::Accept(RawVisitor* visitor) { 209ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski visitor->Visit(static_cast<Derived*>(this)); 21075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} 21175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 2121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T> 2135eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass NodeCastImpl : public RawVisitor { 214cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 215ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski using RawVisitor::Visit; 2161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 217cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski T* value = nullptr; 2181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 219ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void Visit(T* v) override { value = v; } 2201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 2211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T> 223ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam LesinskiT* NodeCast(Node* node) { 224cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski NodeCastImpl<T> visitor; 225ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski node->Accept(&visitor); 226cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return visitor.value; 22775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} 22875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 229cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace xml 230cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace aapt 23175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 232cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#endif // AAPT_XML_DOM_H 233