XmlDom.h revision 5eeaaddffd23d8d85aeb321e3ceea626e42cf9de
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 201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Diagnostics.h" 211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "Resource.h" 221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "ResourceValues.h" 231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/StringPiece.h" 241ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h" 25467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski#include "xml/XmlUtil.h" 2675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 2775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <istream> 2875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <memory> 2975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <string> 3075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#include <vector> 3175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 3275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskinamespace aapt { 3375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskinamespace xml { 3475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 355eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass RawVisitor; 3675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 3775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 3875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Base class for all XML nodes. 3975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 405eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Node { 415eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskipublic: 421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski Node* parent = nullptr; 431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski size_t lineNumber = 0; 441ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski size_t columnNumber = 0; 45d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski std::string comment; 4675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::vector<std::unique_ptr<Node>> children; 4775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 48467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski virtual ~Node() = default; 49467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski 5075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski void addChild(std::unique_ptr<Node> child); 511ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual void accept(RawVisitor* visitor) = 0; 525eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski virtual std::unique_ptr<Node> clone() = 0; 5375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 5475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 5575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 5675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Base class that implements the visitor methods for a 5775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * subclass of Node. 5875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 5975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskitemplate <typename Derived> 605eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass BaseNode : public Node { 615eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskipublic: 621ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual void accept(RawVisitor* visitor) override; 6375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 6475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 6575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 6675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * A Namespace XML node. Can only have one child. 6775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 685eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Namespace : public BaseNode<Namespace> { 695eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskipublic: 70d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski std::string namespacePrefix; 71d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski std::string namespaceUri; 725eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski 735eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski std::unique_ptr<Node> clone() override; 741ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 7575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 761ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistruct AaptAttribute { 7764587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski Maybe<ResourceId> id; 781ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski aapt::Attribute attribute; 7975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 8075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 8175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 8275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * An XML attribute. 8375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 8475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskistruct Attribute { 85d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski std::string namespaceUri; 86d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski std::string name; 87d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski std::string value; 881ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 891ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski Maybe<AaptAttribute> compiledAttribute; 901ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski std::unique_ptr<Item> compiledValue; 9175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 9275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 9375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 9475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * An Element XML node. 9575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 965eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Element : public BaseNode<Element> { 975eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskipublic: 98d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski std::string namespaceUri; 99d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski std::string name; 10075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::vector<Attribute> attributes; 10175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 102d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski Attribute* findAttribute(const StringPiece& ns, const StringPiece& name); 103d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski xml::Element* findChild(const StringPiece& ns, const StringPiece& name); 104d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski xml::Element* findChildWithAttribute(const StringPiece& ns, const StringPiece& name, 105d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski const StringPiece& attrNs, 106d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski const StringPiece& attrName, 107d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski const StringPiece& attrValue); 10875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski std::vector<xml::Element*> getChildElements(); 1095eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski std::unique_ptr<Node> clone() override; 11075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 11175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 11275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 11375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * A Text (CDATA) XML node. Can not have any children. 11475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1155eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Text : public BaseNode<Text> { 1165eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskipublic: 117d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski std::string text; 1185eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski 1195eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski std::unique_ptr<Node> clone() override; 12075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 12175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 12275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 123467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski * An XML resource with a source, name, and XML tree. 124467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski */ 1255eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass XmlResource { 1265eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskipublic: 127467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski ResourceFile file; 128467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski std::unique_ptr<xml::Node> root; 129467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski}; 130467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski 131467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski/** 13275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Inflates an XML DOM from a text stream, logging errors to the logger. 13375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Returns the root node on success, or nullptr on failure. 13475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistd::unique_ptr<XmlResource> inflate(std::istream* in, IDiagnostics* diag, const Source& source); 13675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 13775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 13875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Inflates an XML DOM from a binary ResXMLTree, logging errors to the logger. 13975f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski * Returns the root node on success, or nullptr on failure. 14075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1411ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskistd::unique_ptr<XmlResource> inflate(const void* data, size_t dataLen, IDiagnostics* diag, 1421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski const Source& source); 1431ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 144467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam LesinskiElement* findRootElement(XmlResource* doc); 145ca5638fd85098c3d0a699492751043545f75553aAdam LesinskiElement* findRootElement(Node* node); 146ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski 1471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 1481ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * A visitor interface for the different XML Node subtypes. This will not traverse into 1491ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * children. Use Visitor for that. 1501ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 1515eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass RawVisitor { 1525eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskipublic: 1531ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual ~RawVisitor() = default; 1541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1551ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual void visit(Namespace* node) {} 1561ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual void visit(Element* node) {} 1571ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski virtual void visit(Text* text) {} 1581ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 1591ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1601ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 1611ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Visitor whose default implementation visits the children nodes of any node. 1621ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 1635eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass Visitor : public RawVisitor { 1645eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskipublic: 1651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski using RawVisitor::visit; 1661ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1671ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski void visit(Namespace* node) override { 1681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski visitChildren(node); 1691ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1701ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1711ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski void visit(Element* node) override { 1721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski visitChildren(node); 1731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1741ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1751ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski void visit(Text* text) override { 1761ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski visitChildren(text); 1771ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1781ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 1791ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski void visitChildren(Node* node) { 1801ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski for (auto& child : node->children) { 1811ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski child->accept(this); 1821ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1841ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 18575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 18675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski/** 1871ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * An XML DOM visitor that will record the package name for a namespace prefix. 18875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski */ 1891ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass PackageAwareVisitor : public Visitor, public IPackageDeclStack { 1905eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskipublic: 1915eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski using Visitor::visit; 1925eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski 1935eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski void visit(Namespace* ns) override; 1945eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski Maybe<ExtractedPackage> transformPackageAlias( 1955eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski const StringPiece& alias, const StringPiece& localPackage) const override; 1965eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinski 1971ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiprivate: 1981ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski struct PackageDecl { 199d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski std::string prefix; 200467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski ExtractedPackage package; 2011ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski }; 2021ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2031ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski std::vector<PackageDecl> mPackageDecls; 20475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski}; 20575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 20675f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski// Implementations 20775f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 20875f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinskitemplate <typename Derived> 2091ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskivoid BaseNode<Derived>::accept(RawVisitor* visitor) { 2101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski visitor->visit(static_cast<Derived*>(this)); 21175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} 21275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 2131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T> 2145eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskiclass NodeCastImpl : public RawVisitor { 2155eeaaddffd23d8d85aeb321e3ceea626e42cf9deAdam Lesinskipublic: 2161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski using RawVisitor::visit; 2171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski T* value = nullptr; 2191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski void visit(T* v) override { 2211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski value = v; 2221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 2231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 2241ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskitemplate <typename T> 2261ab598f46c3ff520a67f9d80194847741f3467abAdam LesinskiT* nodeCast(Node* node) { 2271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski NodeCastImpl<T> visitor; 2281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski node->accept(&visitor); 2291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski return visitor.value; 23075f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} 23175f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 23275f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} // namespace xml 23375f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski} // namespace aapt 23475f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski 23575f3a55cc569a9b61f540a85d9828e91bdca5047Adam Lesinski#endif // AAPT_XML_DOM_H 236