xref: /aoo42x/main/xmloff/source/core/DomExport.cxx (revision 63bba73c)
1*63bba73cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*63bba73cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*63bba73cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*63bba73cSAndrew Rist  * distributed with this work for additional information
6*63bba73cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*63bba73cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*63bba73cSAndrew Rist  * "License"); you may not use this file except in compliance
9*63bba73cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*63bba73cSAndrew Rist  *
11*63bba73cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*63bba73cSAndrew Rist  *
13*63bba73cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*63bba73cSAndrew Rist  * software distributed under the License is distributed on an
15*63bba73cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*63bba73cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*63bba73cSAndrew Rist  * specific language governing permissions and limitations
18*63bba73cSAndrew Rist  * under the License.
19*63bba73cSAndrew Rist  *
20*63bba73cSAndrew Rist  *************************************************************/
21*63bba73cSAndrew Rist 
22*63bba73cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_xmloff.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "DomExport.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <xmloff/nmspmap.hxx>
30cdf0e10cSrcweir #include <xmloff/xmlexp.hxx>
31cdf0e10cSrcweir #include "xmloff/xmlerror.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34cdf0e10cSrcweir #include <com/sun/star/uno/Reference.hxx>
35cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx>
36cdf0e10cSrcweir #include <com/sun/star/xml/dom/XAttr.hpp>
37cdf0e10cSrcweir #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
38cdf0e10cSrcweir #include <com/sun/star/xml/dom/XNode.hpp>
39cdf0e10cSrcweir #include <com/sun/star/xml/dom/XElement.hpp>
40cdf0e10cSrcweir #include <com/sun/star/xml/dom/XEntity.hpp>
41cdf0e10cSrcweir #include <com/sun/star/xml/dom/XNotation.hpp>
42cdf0e10cSrcweir #include <com/sun/star/xml/sax/XAttributeList.hpp>
43cdf0e10cSrcweir #include <com/sun/star/xml/dom/NodeType.hpp>
44cdf0e10cSrcweir #include <com/sun/star/xml/dom/XNamedNodeMap.hpp>
45cdf0e10cSrcweir 
46cdf0e10cSrcweir #include <rtl/ustring.hxx>
47cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
48cdf0e10cSrcweir #include <tools/debug.hxx>
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #include <unotools/processfactory.hxx>
51cdf0e10cSrcweir 
52cdf0e10cSrcweir #include <vector>
53cdf0e10cSrcweir 
54cdf0e10cSrcweir 
55cdf0e10cSrcweir using com::sun::star::lang::XMultiServiceFactory;
56cdf0e10cSrcweir using com::sun::star::uno::Reference;
57cdf0e10cSrcweir using com::sun::star::uno::Sequence;
58cdf0e10cSrcweir using com::sun::star::uno::UNO_QUERY;
59cdf0e10cSrcweir using com::sun::star::uno::UNO_QUERY_THROW;
60cdf0e10cSrcweir using std::vector;
61cdf0e10cSrcweir 
62cdf0e10cSrcweir using namespace com::sun::star::xml::dom;
63cdf0e10cSrcweir 
64cdf0e10cSrcweir using rtl::OUString;
65cdf0e10cSrcweir using rtl::OUStringBuffer;
66cdf0e10cSrcweir 
67cdf0e10cSrcweir 
68cdf0e10cSrcweir class DomVisitor
69cdf0e10cSrcweir {
70cdf0e10cSrcweir public:
DomVisitor()71cdf0e10cSrcweir     DomVisitor() {}
~DomVisitor()72cdf0e10cSrcweir     virtual ~DomVisitor() {}
element(const Reference<XElement> &)73cdf0e10cSrcweir     virtual void element( const Reference<XElement>& ) {}
character(const Reference<XCharacterData> &)74cdf0e10cSrcweir     virtual void character( const Reference<XCharacterData>& ) {}
attribute(const Reference<XAttr> &)75cdf0e10cSrcweir     virtual void attribute( const Reference<XAttr>& ) {}
cdata(const Reference<XCDATASection> &)76cdf0e10cSrcweir     virtual void cdata( const Reference<XCDATASection>& ) {}
comment(const Reference<XComment> &)77cdf0e10cSrcweir     virtual void comment( const Reference<XComment>& ) {}
documentFragment(const Reference<XDocumentFragment> &)78cdf0e10cSrcweir     virtual void documentFragment( const Reference<XDocumentFragment>& ) {}
document(const Reference<XDocument> &)79cdf0e10cSrcweir     virtual void document( const Reference<XDocument>& ) {}
documentType(const Reference<XDocumentType> &)80cdf0e10cSrcweir     virtual void documentType( const Reference<XDocumentType>& ) {}
entity(const Reference<XEntity> &)81cdf0e10cSrcweir     virtual void entity( const Reference<XEntity>& ) {}
entityReference(const Reference<XEntityReference> &)82cdf0e10cSrcweir     virtual void entityReference( const Reference<XEntityReference>& ) {}
notation(const Reference<XNotation> &)83cdf0e10cSrcweir     virtual void notation( const Reference<XNotation>& ) {}
processingInstruction(const Reference<XProcessingInstruction> &)84cdf0e10cSrcweir     virtual void processingInstruction( const Reference<XProcessingInstruction>& ) {}
endElement(const Reference<XElement> &)85cdf0e10cSrcweir     virtual void endElement( const Reference<XElement>& ) {}
86cdf0e10cSrcweir };
87cdf0e10cSrcweir 
88cdf0e10cSrcweir void visit( DomVisitor&, const Reference<XDocument>& );
89cdf0e10cSrcweir void visit( DomVisitor&, const Reference<XNode>& );
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 
92cdf0e10cSrcweir 
visitNode(DomVisitor & rVisitor,const Reference<XNode> & xNode)93cdf0e10cSrcweir void visitNode( DomVisitor& rVisitor, const Reference<XNode>& xNode )
94cdf0e10cSrcweir {
95cdf0e10cSrcweir     switch( xNode->getNodeType() )
96cdf0e10cSrcweir     {
97cdf0e10cSrcweir     case NodeType_ATTRIBUTE_NODE:
98cdf0e10cSrcweir         rVisitor.attribute( Reference<XAttr>( xNode, UNO_QUERY_THROW ) );
99cdf0e10cSrcweir         break;
100cdf0e10cSrcweir     case NodeType_CDATA_SECTION_NODE:
101cdf0e10cSrcweir         rVisitor.cdata( Reference<XCDATASection>( xNode, UNO_QUERY_THROW ) );
102cdf0e10cSrcweir         break;
103cdf0e10cSrcweir     case NodeType_COMMENT_NODE:
104cdf0e10cSrcweir         rVisitor.comment( Reference<XComment>( xNode, UNO_QUERY_THROW ) );
105cdf0e10cSrcweir         break;
106cdf0e10cSrcweir     case NodeType_DOCUMENT_FRAGMENT_NODE:
107cdf0e10cSrcweir         rVisitor.documentFragment( Reference<XDocumentFragment>( xNode, UNO_QUERY_THROW ) );
108cdf0e10cSrcweir         break;
109cdf0e10cSrcweir     case NodeType_DOCUMENT_NODE:
110cdf0e10cSrcweir         rVisitor.document( Reference<XDocument>( xNode, UNO_QUERY_THROW ) );
111cdf0e10cSrcweir         break;
112cdf0e10cSrcweir     case NodeType_DOCUMENT_TYPE_NODE:
113cdf0e10cSrcweir         rVisitor.documentType( Reference<XDocumentType>( xNode, UNO_QUERY_THROW ) );
114cdf0e10cSrcweir         break;
115cdf0e10cSrcweir     case NodeType_ELEMENT_NODE:
116cdf0e10cSrcweir         rVisitor.element( Reference<XElement>( xNode, UNO_QUERY_THROW ) );
117cdf0e10cSrcweir         break;
118cdf0e10cSrcweir     case NodeType_ENTITY_NODE:
119cdf0e10cSrcweir         rVisitor.entity( Reference<XEntity>( xNode, UNO_QUERY_THROW ) );
120cdf0e10cSrcweir         break;
121cdf0e10cSrcweir     case NodeType_ENTITY_REFERENCE_NODE:
122cdf0e10cSrcweir         rVisitor.entityReference( Reference<XEntityReference>( xNode, UNO_QUERY_THROW ) );
123cdf0e10cSrcweir         break;
124cdf0e10cSrcweir     case NodeType_NOTATION_NODE:
125cdf0e10cSrcweir         rVisitor.notation( Reference<XNotation>( xNode, UNO_QUERY_THROW ) );
126cdf0e10cSrcweir         break;
127cdf0e10cSrcweir     case NodeType_PROCESSING_INSTRUCTION_NODE:
128cdf0e10cSrcweir         rVisitor.processingInstruction( Reference<XProcessingInstruction>( xNode, UNO_QUERY_THROW ) );
129cdf0e10cSrcweir         break;
130cdf0e10cSrcweir     case NodeType_TEXT_NODE:
131cdf0e10cSrcweir         rVisitor.character( Reference<XCharacterData>( xNode, UNO_QUERY_THROW ) );
132cdf0e10cSrcweir         break;
133cdf0e10cSrcweir     default:
134cdf0e10cSrcweir         DBG_ERROR( "unknown DOM node type" );
135cdf0e10cSrcweir         break;
136cdf0e10cSrcweir     }
137cdf0e10cSrcweir }
138cdf0e10cSrcweir 
visit(DomVisitor & rVisitor,const Reference<XDocument> & xDocument)139cdf0e10cSrcweir void visit( DomVisitor& rVisitor, const Reference<XDocument>& xDocument )
140cdf0e10cSrcweir {
141cdf0e10cSrcweir     visit( rVisitor, Reference<XNode>( xDocument, UNO_QUERY_THROW ) );
142cdf0e10cSrcweir }
143cdf0e10cSrcweir 
visit(DomVisitor & rVisitor,const Reference<XNode> & xNode)144cdf0e10cSrcweir void visit( DomVisitor& rVisitor, const Reference<XNode>& xNode )
145cdf0e10cSrcweir {
146cdf0e10cSrcweir     visitNode( rVisitor, xNode );
147cdf0e10cSrcweir     for( Reference<XNode> xChild = xNode->getFirstChild();
148cdf0e10cSrcweir          xChild.is();
149cdf0e10cSrcweir          xChild = xChild->getNextSibling() )
150cdf0e10cSrcweir     {
151cdf0e10cSrcweir         visit( rVisitor, xChild );
152cdf0e10cSrcweir     }
153cdf0e10cSrcweir     if( xNode->getNodeType() == NodeType_ELEMENT_NODE )
154cdf0e10cSrcweir         rVisitor.endElement( Reference<XElement>( xNode, UNO_QUERY_THROW ) );
155cdf0e10cSrcweir }
156cdf0e10cSrcweir 
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 
159cdf0e10cSrcweir class DomExport: public DomVisitor
160cdf0e10cSrcweir {
161cdf0e10cSrcweir     SvXMLExport& mrExport;
162cdf0e10cSrcweir     vector<SvXMLNamespaceMap> maNamespaces;
163cdf0e10cSrcweir 
164cdf0e10cSrcweir     void pushNamespace();
165cdf0e10cSrcweir     void popNamespace();
166cdf0e10cSrcweir     void addNamespace( const OUString& sPrefix, const OUString& sURI );
167cdf0e10cSrcweir     OUString qualifiedName( const OUString& sPrefix, const OUString& sURI,
168cdf0e10cSrcweir                             const OUString& sLocalName );
169cdf0e10cSrcweir     OUString qualifiedName( const Reference<XNode>&  );
170cdf0e10cSrcweir     OUString qualifiedName( const Reference<XElement>&  );
171cdf0e10cSrcweir     OUString qualifiedName( const Reference<XAttr>&  );
172cdf0e10cSrcweir     void addAttribute( const Reference<XAttr>& );
173cdf0e10cSrcweir 
174cdf0e10cSrcweir public:
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     DomExport( SvXMLExport& rExport );
177cdf0e10cSrcweir     virtual ~DomExport();
178cdf0e10cSrcweir 
179cdf0e10cSrcweir     virtual void element( const Reference<XElement>& );
180cdf0e10cSrcweir     virtual void endElement( const Reference<XElement>& );
181cdf0e10cSrcweir     virtual void character( const Reference<XCharacterData>& );
182cdf0e10cSrcweir };
183cdf0e10cSrcweir 
DomExport(SvXMLExport & rExport)184cdf0e10cSrcweir DomExport::DomExport( SvXMLExport& rExport ) :
185cdf0e10cSrcweir     mrExport( rExport )
186cdf0e10cSrcweir {
187cdf0e10cSrcweir     maNamespaces.push_back( rExport.GetNamespaceMap() );
188cdf0e10cSrcweir }
189cdf0e10cSrcweir 
~DomExport()190cdf0e10cSrcweir DomExport::~DomExport()
191cdf0e10cSrcweir {
192cdf0e10cSrcweir     DBG_ASSERT( maNamespaces.size() == 1, "namespace missing" );
193cdf0e10cSrcweir     maNamespaces.clear();
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
pushNamespace()196cdf0e10cSrcweir void DomExport::pushNamespace()
197cdf0e10cSrcweir {
198cdf0e10cSrcweir     maNamespaces.push_back( maNamespaces.back() );
199cdf0e10cSrcweir }
200cdf0e10cSrcweir 
popNamespace()201cdf0e10cSrcweir void DomExport::popNamespace()
202cdf0e10cSrcweir {
203cdf0e10cSrcweir     maNamespaces.pop_back();
204cdf0e10cSrcweir }
205cdf0e10cSrcweir 
addNamespace(const OUString & sPrefix,const OUString & sURI)206cdf0e10cSrcweir void DomExport::addNamespace( const OUString& sPrefix, const OUString& sURI )
207cdf0e10cSrcweir {
208cdf0e10cSrcweir     SvXMLNamespaceMap& rMap = maNamespaces.back();
209cdf0e10cSrcweir     sal_uInt16 nKey = rMap.GetKeyByPrefix( sPrefix );
210cdf0e10cSrcweir 
211cdf0e10cSrcweir     // we need to register the namespace, if either the prefix isn't known or
212cdf0e10cSrcweir     // is used for a different namespace
213cdf0e10cSrcweir     if( nKey == XML_NAMESPACE_UNKNOWN  ||
214cdf0e10cSrcweir         rMap.GetNameByKey( nKey ) != sURI )
215cdf0e10cSrcweir     {
216cdf0e10cSrcweir         // add prefix to map, and add declaration
217cdf0e10cSrcweir         rMap.Add( sPrefix, sURI );
218cdf0e10cSrcweir         mrExport.AddAttribute(
219cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "xmlns:" ) ) + sPrefix,
220cdf0e10cSrcweir             sURI );
221cdf0e10cSrcweir     }
222cdf0e10cSrcweir }
223cdf0e10cSrcweir 
qualifiedName(const OUString & sPrefix,const OUString & sURI,const OUString & sLocalName)224cdf0e10cSrcweir OUString DomExport::qualifiedName( const OUString& sPrefix,
225cdf0e10cSrcweir                                    const OUString& sURI,
226cdf0e10cSrcweir                                    const OUString& sLocalName )
227cdf0e10cSrcweir {
228cdf0e10cSrcweir     OUStringBuffer sBuffer;
229cdf0e10cSrcweir     if( ( sPrefix.getLength() > 0 ) && ( sURI.getLength() > 0 ) )
230cdf0e10cSrcweir     {
231cdf0e10cSrcweir         addNamespace( sPrefix, sURI );
232cdf0e10cSrcweir         sBuffer.append( sPrefix );
233cdf0e10cSrcweir         sBuffer.append( sal_Unicode( ':' ) );
234cdf0e10cSrcweir     }
235cdf0e10cSrcweir     sBuffer.append( sLocalName );
236cdf0e10cSrcweir     return sBuffer.makeStringAndClear();
237cdf0e10cSrcweir }
238cdf0e10cSrcweir 
qualifiedName(const Reference<XNode> & xNode)239cdf0e10cSrcweir OUString DomExport::qualifiedName( const Reference<XNode>& xNode )
240cdf0e10cSrcweir {
241cdf0e10cSrcweir     return qualifiedName( xNode->getPrefix(), xNode->getNamespaceURI(),
242cdf0e10cSrcweir                           xNode->getNodeName() );
243cdf0e10cSrcweir }
244cdf0e10cSrcweir 
qualifiedName(const Reference<XElement> & xElement)245cdf0e10cSrcweir OUString DomExport::qualifiedName( const Reference<XElement>& xElement )
246cdf0e10cSrcweir {
247cdf0e10cSrcweir     return qualifiedName( xElement->getPrefix(), xElement->getNamespaceURI(),
248cdf0e10cSrcweir                           xElement->getNodeName() );
249cdf0e10cSrcweir }
250cdf0e10cSrcweir 
qualifiedName(const Reference<XAttr> & xAttr)251cdf0e10cSrcweir OUString DomExport::qualifiedName( const Reference<XAttr>& xAttr )
252cdf0e10cSrcweir {
253cdf0e10cSrcweir     return qualifiedName( xAttr->getPrefix(), xAttr->getNamespaceURI(),
254cdf0e10cSrcweir                           xAttr->getNodeName() );
255cdf0e10cSrcweir }
256cdf0e10cSrcweir 
addAttribute(const Reference<XAttr> & xAttribute)257cdf0e10cSrcweir void DomExport::addAttribute( const Reference<XAttr>& xAttribute )
258cdf0e10cSrcweir {
259cdf0e10cSrcweir     mrExport.AddAttribute( qualifiedName( xAttribute ),
260cdf0e10cSrcweir                            xAttribute->getNodeValue() );
261cdf0e10cSrcweir }
262cdf0e10cSrcweir 
element(const Reference<XElement> & xElement)263cdf0e10cSrcweir void DomExport::element( const Reference<XElement>& xElement )
264cdf0e10cSrcweir {
265cdf0e10cSrcweir     pushNamespace();
266cdf0e10cSrcweir 
267cdf0e10cSrcweir     // write attributes
268cdf0e10cSrcweir     Reference<XNamedNodeMap> xAttributes = xElement->getAttributes();
269cdf0e10cSrcweir     sal_Int32 nLength = xAttributes.is() ? xAttributes->getLength() : 0;
270cdf0e10cSrcweir     for( sal_Int32 n = 0; n < nLength; n++ )
271cdf0e10cSrcweir     {
272cdf0e10cSrcweir         addAttribute( Reference<XAttr>( xAttributes->item( n ), UNO_QUERY_THROW ) );
273cdf0e10cSrcweir     }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     // write name
276cdf0e10cSrcweir     mrExport.StartElement( qualifiedName( xElement ), sal_False );
277cdf0e10cSrcweir }
278cdf0e10cSrcweir 
endElement(const Reference<XElement> & xElement)279cdf0e10cSrcweir void DomExport::endElement( const Reference<XElement>& xElement )
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     mrExport.EndElement( qualifiedName( xElement ), sal_False );
282cdf0e10cSrcweir     popNamespace();
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
character(const Reference<XCharacterData> & xChars)285cdf0e10cSrcweir void DomExport::character( const Reference<XCharacterData>& xChars )
286cdf0e10cSrcweir {
287cdf0e10cSrcweir     mrExport.Characters( xChars->getNodeValue() );
288cdf0e10cSrcweir }
289cdf0e10cSrcweir 
290cdf0e10cSrcweir 
exportDom(SvXMLExport & rExport,const Reference<XDocument> & xDocument)291cdf0e10cSrcweir void exportDom( SvXMLExport& rExport, const Reference<XDocument>& xDocument )
292cdf0e10cSrcweir {
293cdf0e10cSrcweir     DomExport aDomExport( rExport );
294cdf0e10cSrcweir     visit( aDomExport, xDocument );
295cdf0e10cSrcweir }
296cdf0e10cSrcweir 
exportDom(SvXMLExport & rExport,const Reference<XNode> & xNode)297cdf0e10cSrcweir void exportDom( SvXMLExport& rExport, const Reference<XNode>& xNode )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir     DomExport aDomExport( rExport );
300cdf0e10cSrcweir     visit( aDomExport, xNode );
301cdf0e10cSrcweir }
302