Update ooo320-m1
[ooovba.git] / xmloff / source / core / DomExport.cxx
blobff512474c88c13ea27db540d25a2d5ef3aa88c1f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: DomExport.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
34 #include "DomExport.hxx"
36 #include <xmloff/nmspmap.hxx>
37 #include <xmloff/xmlexp.hxx>
38 #include "xmlerror.hxx"
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/uno/Reference.hxx>
42 #include <com/sun/star/uno/Sequence.hxx>
43 #include <com/sun/star/xml/dom/XAttr.hpp>
44 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
45 #include <com/sun/star/xml/dom/XNode.hpp>
46 #include <com/sun/star/xml/dom/XElement.hpp>
47 #include <com/sun/star/xml/dom/XEntity.hpp>
48 #include <com/sun/star/xml/dom/XNotation.hpp>
49 #include <com/sun/star/xml/sax/XAttributeList.hpp>
50 #include <com/sun/star/xml/dom/NodeType.hpp>
51 #include <com/sun/star/xml/dom/XNamedNodeMap.hpp>
53 #include <rtl/ustring.hxx>
54 #include <rtl/ustrbuf.hxx>
55 #include <tools/debug.hxx>
57 #include <unotools/processfactory.hxx>
59 #include <vector>
62 using com::sun::star::lang::XMultiServiceFactory;
63 using com::sun::star::uno::Reference;
64 using com::sun::star::uno::Sequence;
65 using com::sun::star::uno::UNO_QUERY;
66 using com::sun::star::uno::UNO_QUERY_THROW;
67 using std::vector;
69 using namespace com::sun::star::xml::dom;
71 using rtl::OUString;
72 using rtl::OUStringBuffer;
75 class DomVisitor
77 public:
78 DomVisitor() {}
79 virtual ~DomVisitor() {}
80 virtual void element( const Reference<XElement>& ) {}
81 virtual void character( const Reference<XCharacterData>& ) {}
82 virtual void attribute( const Reference<XAttr>& ) {}
83 virtual void cdata( const Reference<XCDATASection>& ) {}
84 virtual void comment( const Reference<XComment>& ) {}
85 virtual void documentFragment( const Reference<XDocumentFragment>& ) {}
86 virtual void document( const Reference<XDocument>& ) {}
87 virtual void documentType( const Reference<XDocumentType>& ) {}
88 virtual void entity( const Reference<XEntity>& ) {}
89 virtual void entityReference( const Reference<XEntityReference>& ) {}
90 virtual void notation( const Reference<XNotation>& ) {}
91 virtual void processingInstruction( const Reference<XProcessingInstruction>& ) {}
92 virtual void endElement( const Reference<XElement>& ) {}
95 void visit( DomVisitor&, const Reference<XDocument>& );
96 void visit( DomVisitor&, const Reference<XNode>& );
100 void visitNode( DomVisitor& rVisitor, const Reference<XNode>& xNode )
102 switch( xNode->getNodeType() )
104 case NodeType_ATTRIBUTE_NODE:
105 rVisitor.attribute( Reference<XAttr>( xNode, UNO_QUERY_THROW ) );
106 break;
107 case NodeType_CDATA_SECTION_NODE:
108 rVisitor.cdata( Reference<XCDATASection>( xNode, UNO_QUERY_THROW ) );
109 break;
110 case NodeType_COMMENT_NODE:
111 rVisitor.comment( Reference<XComment>( xNode, UNO_QUERY_THROW ) );
112 break;
113 case NodeType_DOCUMENT_FRAGMENT_NODE:
114 rVisitor.documentFragment( Reference<XDocumentFragment>( xNode, UNO_QUERY_THROW ) );
115 break;
116 case NodeType_DOCUMENT_NODE:
117 rVisitor.document( Reference<XDocument>( xNode, UNO_QUERY_THROW ) );
118 break;
119 case NodeType_DOCUMENT_TYPE_NODE:
120 rVisitor.documentType( Reference<XDocumentType>( xNode, UNO_QUERY_THROW ) );
121 break;
122 case NodeType_ELEMENT_NODE:
123 rVisitor.element( Reference<XElement>( xNode, UNO_QUERY_THROW ) );
124 break;
125 case NodeType_ENTITY_NODE:
126 rVisitor.entity( Reference<XEntity>( xNode, UNO_QUERY_THROW ) );
127 break;
128 case NodeType_ENTITY_REFERENCE_NODE:
129 rVisitor.entityReference( Reference<XEntityReference>( xNode, UNO_QUERY_THROW ) );
130 break;
131 case NodeType_NOTATION_NODE:
132 rVisitor.notation( Reference<XNotation>( xNode, UNO_QUERY_THROW ) );
133 break;
134 case NodeType_PROCESSING_INSTRUCTION_NODE:
135 rVisitor.processingInstruction( Reference<XProcessingInstruction>( xNode, UNO_QUERY_THROW ) );
136 break;
137 case NodeType_TEXT_NODE:
138 rVisitor.character( Reference<XCharacterData>( xNode, UNO_QUERY_THROW ) );
139 break;
140 default:
141 DBG_ERROR( "unknown DOM node type" );
142 break;
146 void visit( DomVisitor& rVisitor, const Reference<XDocument>& xDocument )
148 visit( rVisitor, Reference<XNode>( xDocument, UNO_QUERY_THROW ) );
151 void visit( DomVisitor& rVisitor, const Reference<XNode>& xNode )
153 visitNode( rVisitor, xNode );
154 for( Reference<XNode> xChild = xNode->getFirstChild();
155 xChild.is();
156 xChild = xChild->getNextSibling() )
158 visit( rVisitor, xChild );
160 if( xNode->getNodeType() == NodeType_ELEMENT_NODE )
161 rVisitor.endElement( Reference<XElement>( xNode, UNO_QUERY_THROW ) );
166 class DomExport: public DomVisitor
168 SvXMLExport& mrExport;
169 vector<SvXMLNamespaceMap> maNamespaces;
171 void pushNamespace();
172 void popNamespace();
173 void addNamespace( const OUString& sPrefix, const OUString& sURI );
174 OUString qualifiedName( const OUString& sPrefix, const OUString& sURI,
175 const OUString& sLocalName );
176 OUString qualifiedName( const Reference<XNode>& );
177 OUString qualifiedName( const Reference<XElement>& );
178 OUString qualifiedName( const Reference<XAttr>& );
179 void addAttribute( const Reference<XAttr>& );
181 public:
183 DomExport( SvXMLExport& rExport );
184 virtual ~DomExport();
186 virtual void element( const Reference<XElement>& );
187 virtual void endElement( const Reference<XElement>& );
188 virtual void character( const Reference<XCharacterData>& );
191 DomExport::DomExport( SvXMLExport& rExport ) :
192 mrExport( rExport )
194 maNamespaces.push_back( rExport.GetNamespaceMap() );
197 DomExport::~DomExport()
199 DBG_ASSERT( maNamespaces.size() == 1, "namespace missing" );
200 maNamespaces.clear();
203 void DomExport::pushNamespace()
205 maNamespaces.push_back( maNamespaces.back() );
208 void DomExport::popNamespace()
210 maNamespaces.pop_back();
213 void DomExport::addNamespace( const OUString& sPrefix, const OUString& sURI )
215 SvXMLNamespaceMap& rMap = maNamespaces.back();
216 sal_uInt16 nKey = rMap.GetKeyByPrefix( sPrefix );
218 // we need to register the namespace, if either the prefix isn't known or
219 // is used for a different namespace
220 if( nKey == XML_NAMESPACE_UNKNOWN ||
221 rMap.GetNameByKey( nKey ) != sURI )
223 // add prefix to map, and add declaration
224 rMap.Add( sPrefix, sURI );
225 mrExport.AddAttribute(
226 OUString( RTL_CONSTASCII_USTRINGPARAM( "xmlns:" ) ) + sPrefix,
227 sURI );
231 OUString DomExport::qualifiedName( const OUString& sPrefix,
232 const OUString& sURI,
233 const OUString& sLocalName )
235 OUStringBuffer sBuffer;
236 if( ( sPrefix.getLength() > 0 ) && ( sURI.getLength() > 0 ) )
238 addNamespace( sPrefix, sURI );
239 sBuffer.append( sPrefix );
240 sBuffer.append( sal_Unicode( ':' ) );
242 sBuffer.append( sLocalName );
243 return sBuffer.makeStringAndClear();
246 OUString DomExport::qualifiedName( const Reference<XNode>& xNode )
248 return qualifiedName( xNode->getPrefix(), xNode->getNamespaceURI(),
249 xNode->getNodeName() );
252 OUString DomExport::qualifiedName( const Reference<XElement>& xElement )
254 return qualifiedName( xElement->getPrefix(), xElement->getNamespaceURI(),
255 xElement->getNodeName() );
258 OUString DomExport::qualifiedName( const Reference<XAttr>& xAttr )
260 return qualifiedName( xAttr->getPrefix(), xAttr->getNamespaceURI(),
261 xAttr->getNodeName() );
264 void DomExport::addAttribute( const Reference<XAttr>& xAttribute )
266 mrExport.AddAttribute( qualifiedName( xAttribute ),
267 xAttribute->getNodeValue() );
270 void DomExport::element( const Reference<XElement>& xElement )
272 pushNamespace();
274 // write attributes
275 Reference<XNamedNodeMap> xAttributes = xElement->getAttributes();
276 sal_Int32 nLength = xAttributes.is() ? xAttributes->getLength() : 0;
277 for( sal_Int32 n = 0; n < nLength; n++ )
279 addAttribute( Reference<XAttr>( xAttributes->item( n ), UNO_QUERY_THROW ) );
282 // write name
283 mrExport.StartElement( qualifiedName( xElement ), sal_False );
286 void DomExport::endElement( const Reference<XElement>& xElement )
288 mrExport.EndElement( qualifiedName( xElement ), sal_False );
289 popNamespace();
292 void DomExport::character( const Reference<XCharacterData>& xChars )
294 mrExport.Characters( xChars->getNodeValue() );
298 void exportDom( SvXMLExport& rExport, const Reference<XDocument>& xDocument )
300 DomExport aDomExport( rExport );
301 visit( aDomExport, xDocument );
304 void exportDom( SvXMLExport& rExport, const Reference<XNode>& xNode )
306 DomExport aDomExport( rExport );
307 visit( aDomExport, xNode );