Bump for 3.6-28
[LibreOffice.git] / l10ntools / source / xmlparse.cxx
blobbcad1041623293dbf2be2e69ee5b308ca89619bf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "sal/config.h"
31 #include <iterator> /* std::iterator*/
33 #include <stdio.h>
34 #include <sal/alloca.h>
36 #include "common.hxx"
37 #include "xmlparse.hxx"
38 #include <fstream>
39 #include <iostream>
40 #include <osl/mutex.hxx>
41 #include <osl/thread.hxx>
42 #include <rtl/strbuf.hxx>
44 using namespace std;
45 using namespace osl;
48 // class XMLChildNode
51 /*****************************************************************************/
52 XMLChildNode::XMLChildNode( XMLParentNode *pPar )
53 /*****************************************************************************/
54 : pParent( pPar )
56 if ( pParent )
57 pParent->AddChild( this );
61 /*****************************************************************************/
62 XMLChildNode::XMLChildNode( const XMLChildNode& obj)
63 /*****************************************************************************/
64 : XMLNode(obj),
65 pParent(obj.pParent){}
67 /*****************************************************************************/
68 XMLChildNode& XMLChildNode::operator=(const XMLChildNode& obj){
69 /*****************************************************************************/
70 if(this != &obj){
71 pParent=obj.pParent;
73 return *this;
76 // class XMLParentNode
80 /*****************************************************************************/
81 XMLParentNode::~XMLParentNode()
82 /*****************************************************************************/
84 if( pChildList ){
85 RemoveAndDeleteAllChildren();
86 delete pChildList;
87 pChildList = NULL;
89 pChildList = NULL;
91 /*****************************************************************************/
92 XMLParentNode::XMLParentNode( const XMLParentNode& obj)
93 /*****************************************************************************/
94 : XMLChildNode( obj )
96 if( obj.pChildList ){
97 pChildList=new XMLChildNodeList();
98 XMLChildNode* pNode = NULL;
99 for ( size_t i = 0; i < obj.pChildList->size(); i++ ){
100 pNode = (*obj.pChildList)[ i ];
101 if( pNode != NULL){
102 switch(pNode->GetNodeType()){
103 case XML_NODE_TYPE_ELEMENT:
104 AddChild( new XMLElement( *static_cast<XMLElement* >(pNode) ) ); break;
105 case XML_NODE_TYPE_DATA:
106 AddChild( new XMLData ( *static_cast<XMLData* > (pNode) ) ); break;
107 case XML_NODE_TYPE_COMMENT:
108 AddChild( new XMLComment( *static_cast<XMLComment* >(pNode) ) ); break;
109 case XML_NODE_TYPE_DEFAULT:
110 AddChild( new XMLDefault( *static_cast<XMLDefault* >(pNode) ) ); break;
111 default: fprintf(stdout,"XMLParentNode::XMLParentNode( const XMLParentNode& obj) strange obj");
115 }else pChildList = NULL;
117 /*****************************************************************************/
118 XMLParentNode& XMLParentNode::operator=(const XMLParentNode& obj){
119 /*****************************************************************************/
120 if(this!=&obj){
121 XMLChildNode::operator=(obj);
122 if( pChildList ){
123 RemoveAndDeleteAllChildren();
124 delete pChildList;
125 pChildList = NULL;
127 if( obj.pChildList ){
128 pChildList=new XMLChildNodeList();
129 for ( size_t i = 0; i < obj.pChildList->size(); i++ )
130 AddChild( (*obj.pChildList)[ i ] );
131 }else pChildList = NULL;
134 return *this;
136 /*****************************************************************************/
137 void XMLParentNode::AddChild( XMLChildNode *pChild )
138 /*****************************************************************************/
140 if ( !pChildList )
141 pChildList = new XMLChildNodeList();
142 pChildList->push_back( pChild );
145 /*****************************************************************************/
146 void XMLParentNode::AddChild( XMLChildNode *pChild , size_t pos )
147 /*****************************************************************************/
149 if ( !pChildList )
150 pChildList = new XMLChildNodeList();
151 if ( pos < pChildList->size() )
153 XMLChildNodeList::iterator it = pChildList->begin();
154 ::std::advance( it, pos );
155 pChildList->insert( it, pChild );
156 } else {
157 pChildList->push_back( pChild );
161 /*****************************************************************************/
162 void XMLParentNode::RemoveAndDeleteAllChildren(){
163 /*****************************************************************************/
164 if ( pChildList ) {
165 for ( size_t i = 0; i < pChildList->size(); i++ )
166 delete (*pChildList)[ i ];
167 pChildList->clear();
172 // class XMLFile
175 /*****************************************************************************/
176 sal_uInt16 XMLFile::GetNodeType()
177 /*****************************************************************************/
179 return XML_NODE_TYPE_FILE;
182 void XMLFile::Write( rtl::OString const &aFilename )
184 std::ofstream s(
185 aFilename.getStr(), std::ios_base::out | std::ios_base::trunc);
186 if (!s.is_open()) {
187 std::cerr
188 << "Error: helpex cannot create file " << aFilename.getStr()
189 << '\n';
190 std::exit(EXIT_FAILURE);
192 Write(s);
193 s.close();
196 void XMLFile::WriteString( ofstream &rStream, const rtl::OUString &sString )
198 rtl::OString sText(rtl::OUStringToOString(sString, RTL_TEXTENCODING_UTF8));
199 rStream << sText.getStr();
202 sal_Bool XMLFile::Write( ofstream &rStream , XMLNode *pCur )
204 if ( !pCur )
205 Write( rStream, this );
206 else {
207 switch( pCur->GetNodeType()) {
208 case XML_NODE_TYPE_FILE: {
209 if( GetChildList())
210 for ( size_t i = 0; i < GetChildList()->size(); i++ )
211 Write( rStream, (*GetChildList())[ i ] );
213 break;
214 case XML_NODE_TYPE_ELEMENT: {
215 XMLElement *pElement = ( XMLElement * ) pCur;
216 rStream << "<";
217 WriteString( rStream, pElement->GetName());
218 if ( pElement->GetAttributeList())
219 for ( size_t j = 0; j < pElement->GetAttributeList()->size(); j++ ) {
220 rStream << " ";
221 rtl::OUString sData( (*pElement->GetAttributeList())[ j ]->GetName() );
222 XMLUtil::QuotHTML( sData );
223 WriteString( rStream , sData );
224 rStream << "=\"";
225 sData = (*pElement->GetAttributeList())[ j ]->GetValue();
226 XMLUtil::QuotHTML( sData );
227 WriteString( rStream , sData );
228 rStream << "\"";
230 if ( !pElement->GetChildList())
231 rStream << "/>";
232 else {
233 rStream << ">";
234 for ( size_t k = 0; k < pElement->GetChildList()->size(); k++ )
235 Write( rStream, (*pElement->GetChildList())[ k ] );
236 rStream << "</";
237 WriteString( rStream, pElement->GetName());
238 rStream << ">";
241 break;
242 case XML_NODE_TYPE_DATA: {
243 XMLData *pData = ( XMLData * ) pCur;
244 rtl::OUString sData( pData->GetData());
245 XMLUtil::QuotHTML( sData );
246 WriteString( rStream, sData );
248 break;
249 case XML_NODE_TYPE_COMMENT: {
250 XMLComment *pComment = ( XMLComment * ) pCur;
251 rStream << "<!--";
252 WriteString( rStream, pComment->GetComment());
253 rStream << "-->";
255 break;
256 case XML_NODE_TYPE_DEFAULT: {
257 XMLDefault *pDefault = ( XMLDefault * ) pCur;
258 WriteString( rStream, pDefault->GetDefault());
260 break;
263 return sal_True;
267 void XMLFile::Print( XMLNode *pCur, sal_uInt16 nLevel )
270 if ( !pCur )
271 Print( this );
272 else {
273 switch( pCur->GetNodeType()) {
274 case XML_NODE_TYPE_FILE: {
275 if( GetChildList())
276 for ( size_t i = 0; i < GetChildList()->size(); i++ )
277 Print( (*GetChildList())[ i ] );
279 break;
280 case XML_NODE_TYPE_ELEMENT: {
281 XMLElement *pElement = ( XMLElement * ) pCur;
283 fprintf( stdout, "<%s", rtl::OUStringToOString(pElement->GetName(), RTL_TEXTENCODING_UTF8).getStr());
284 if ( pElement->GetAttributeList())
286 for (size_t j = 0; j < pElement->GetAttributeList()->size(); ++j)
288 rtl::OString aAttrName(rtl::OUStringToOString((*pElement->GetAttributeList())[j]->GetName(),
289 RTL_TEXTENCODING_UTF8));
290 if (!aAttrName.equalsIgnoreAsciiCase(XML_LANG))
292 fprintf( stdout, " %s=\"%s\"",
293 aAttrName.getStr(),
294 rtl::OUStringToOString( (*pElement->GetAttributeList())[ j ]->GetValue(),
295 RTL_TEXTENCODING_UTF8).getStr());
299 if ( !pElement->GetChildList())
300 fprintf( stdout, "/>" );
301 else {
302 fprintf( stdout, ">" );
303 for ( size_t k = 0; k < pElement->GetChildList()->size(); k++ )
304 Print( (*pElement->GetChildList())[ k ], nLevel + 1 );
305 fprintf( stdout, "</%s>", rtl::OUStringToOString(pElement->GetName(), RTL_TEXTENCODING_UTF8).getStr());
308 break;
309 case XML_NODE_TYPE_DATA: {
310 XMLData *pData = ( XMLData * ) pCur;
311 rtl::OUString sData = pData->GetData();
312 fprintf( stdout, "%s", rtl::OUStringToOString(sData, RTL_TEXTENCODING_UTF8).getStr());
314 break;
315 case XML_NODE_TYPE_COMMENT: {
316 XMLComment *pComment = ( XMLComment * ) pCur;
317 fprintf( stdout, "<!--%s-->", rtl::OUStringToOString(pComment->GetComment(), RTL_TEXTENCODING_UTF8).getStr());
319 break;
320 case XML_NODE_TYPE_DEFAULT: {
321 XMLDefault *pDefault = ( XMLDefault * ) pCur;
322 fprintf( stdout, "%s", rtl::OUStringToOString(pDefault->GetDefault(), RTL_TEXTENCODING_UTF8).getStr());
324 break;
328 XMLFile::~XMLFile()
330 if( XMLStrings != NULL ){
331 XMLHashMap::iterator pos = XMLStrings->begin();
332 for( ; pos != XMLStrings->end() ; ++pos ){
333 delete pos->second; // Check and delete content also ?
335 delete XMLStrings;
336 XMLStrings = NULL;
339 /*****************************************************************************/
340 XMLFile::XMLFile( const rtl::OUString &rFileName ) // the file name, empty if created from memory stream
341 /*****************************************************************************/
342 : XMLParentNode( NULL ),
343 sFileName ( rFileName ),
344 ID ( "id" ),
345 OLDREF ( "oldref" ),
346 XML_LANG ( "xml-lang" ),
347 XMLStrings ( NULL )
350 nodes_localize.insert( TagMap::value_type(rtl::OString(RTL_CONSTASCII_STRINGPARAM("bookmark")) , sal_True) );
351 nodes_localize.insert( TagMap::value_type(rtl::OString(RTL_CONSTASCII_STRINGPARAM("variable")) , sal_True) );
352 nodes_localize.insert( TagMap::value_type(rtl::OString(RTL_CONSTASCII_STRINGPARAM("paragraph")) , sal_True) );
353 nodes_localize.insert( TagMap::value_type(rtl::OString(RTL_CONSTASCII_STRINGPARAM("alt")) , sal_True) );
354 nodes_localize.insert( TagMap::value_type(rtl::OString(RTL_CONSTASCII_STRINGPARAM("caption")) , sal_True) );
355 nodes_localize.insert( TagMap::value_type(rtl::OString(RTL_CONSTASCII_STRINGPARAM("title")) , sal_True) );
356 nodes_localize.insert( TagMap::value_type(rtl::OString(RTL_CONSTASCII_STRINGPARAM("link")) , sal_True) );
358 /*****************************************************************************/
359 void XMLFile::Extract( XMLFile *pCur )
360 /*****************************************************************************/
362 if( XMLStrings != NULL ) delete XMLStrings; // Elements ?
364 XMLStrings = new XMLHashMap();
365 if ( !pCur )
366 SearchL10NElements( this );
367 else {
368 if( pCur->GetNodeType()==XML_NODE_TYPE_FILE) {
369 SearchL10NElements(pCur);
374 /*****************************************************************************/
375 void XMLFile::InsertL10NElement( XMLElement* pElement ){
376 /*****************************************************************************/
377 rtl::OString tmpStr,id,oldref,language("");
378 LangHashMap* elem;
380 if( pElement->GetAttributeList() != NULL ){
381 for ( size_t j = 0; j < pElement->GetAttributeList()->size(); j++ )
383 tmpStr=rtl::OUStringToOString((*pElement->GetAttributeList())[ j ]->GetName(), RTL_TEXTENCODING_UTF8);
384 if (tmpStr == ID) { // Get the "id" Attribute
385 id = rtl::OUStringToOString((*pElement->GetAttributeList())[ j ]->GetValue(),RTL_TEXTENCODING_UTF8);
387 if (tmpStr == XML_LANG) { // Get the "xml-lang" Attribute
388 language = rtl::OUStringToOString((*pElement->GetAttributeList())[j]->GetValue(),RTL_TEXTENCODING_UTF8);
392 }else{
393 fprintf(stdout,"XMLFile::InsertL10NElement: No AttributeList found");
394 fprintf(stdout,"++++++++++++++++++++++++++++++++++++++++++++++++++");
395 Print( pElement , 0 );
396 fprintf(stdout,"++++++++++++++++++++++++++++++++++++++++++++++++++");
399 XMLHashMap::iterator pos = XMLStrings->find( id );
400 if( pos == XMLStrings->end() ){ // No instanze , create new one
401 elem = new LangHashMap();
402 (*elem)[ language ]=pElement;
403 XMLStrings->insert( XMLHashMap::value_type( id , elem ) );
404 order.push_back( id );
405 }else{ // Already there
406 elem=pos->second;
407 if ( (*elem)[ language ] )
409 fprintf(stdout,"Error: Duplicated entry. ID = %s LANG = %s in File %s\n", id.getStr(), language.getStr(), rtl::OUStringToOString(sFileName, RTL_TEXTENCODING_ASCII_US).getStr() );
410 exit( -1 );
412 (*elem)[ language ]=pElement;
416 XMLFile::XMLFile( const XMLFile& obj )
417 /*****************************************************************************/
418 : XMLParentNode( obj ),
419 sFileName ( obj.sFileName ),
420 ID ( "id" ),
421 OLDREF ( "oldref" ),
422 XML_LANG ( "xml-lang" ),
423 XMLStrings ( NULL )
425 if( this!=&obj )
427 nodes_localize =obj.nodes_localize;
428 order =obj.order;
432 /*****************************************************************************/
433 XMLFile& XMLFile::operator=(const XMLFile& obj){
434 /*****************************************************************************/
435 if( this!=&obj ){
437 XMLParentNode::operator=(obj);
439 nodes_localize =obj.nodes_localize;
440 order =obj.order;
442 if( XMLStrings ) delete XMLStrings;
444 if( obj.XMLStrings )
446 XMLStrings = new XMLHashMap();
447 for( XMLHashMap::iterator pos = obj.XMLStrings->begin() ; pos != obj.XMLStrings->end() ; ++pos )
449 LangHashMap* elem=pos->second;
450 LangHashMap* newelem = new LangHashMap();
451 for(LangHashMap::iterator pos2=elem->begin(); pos2!=elem->end();++pos2){
452 (*newelem)[ pos2->first ] = new XMLElement( *pos2->second );
454 (*XMLStrings)[ pos->first ] = newelem;
458 return *this;
462 /*****************************************************************************/
463 void XMLFile::SearchL10NElements( XMLParentNode *pCur , int pos)
464 /*****************************************************************************/
466 static const rtl::OString LOCALIZE("localize");
467 static const rtl::OString THEID("id");
468 bool bInsert = true;
469 if ( !pCur )
470 SearchL10NElements( this );
471 else {
472 switch( pCur->GetNodeType()) {
473 case XML_NODE_TYPE_FILE: {
474 XMLParentNode* pElement;
475 if( GetChildList()){
476 for ( size_t i = 0; i < GetChildList()->size(); i++ ){
477 pElement = (XMLParentNode*) (*GetChildList())[ i ];
478 if( pElement->GetNodeType() == XML_NODE_TYPE_ELEMENT ) SearchL10NElements( pElement , i);
482 break;
483 case XML_NODE_TYPE_ELEMENT: {
484 XMLElement *pElement = ( XMLElement * ) pCur;
485 rtl::OString sName(rtl::OUStringToOString(pElement->GetName(), RTL_TEXTENCODING_ASCII_US).toAsciiLowerCase());
486 rtl::OString language,tmpStrVal,oldref;
487 if ( pElement->GetAttributeList())
489 for ( size_t j = 0 , cnt = pElement->GetAttributeList()->size(); j < cnt && bInsert; ++j )
491 const rtl::OString tmpStr = rtl::OUStringToOString((*pElement->GetAttributeList())[j]->GetName(), RTL_TEXTENCODING_UTF8);
492 if (tmpStr == THEID) { // Get the "id" Attribute
493 tmpStrVal=rtl::OUStringToOString( (*pElement->GetAttributeList())[ j ]->GetValue(),RTL_TEXTENCODING_UTF8 );
495 if (tmpStr == LOCALIZE) { // Get the "localize" Attribute
496 bInsert=false;
498 if (tmpStr == XML_LANG) { // Get the "xml-lang" Attribute
499 language=rtl::OUStringToOString( (*pElement->GetAttributeList())[ j ]->GetValue(),RTL_TEXTENCODING_UTF8 );
501 if (tmpStr == OLDREF) { // Get the "oldref" Attribute
502 oldref=rtl::OUStringToOString( (*pElement->GetAttributeList())[ j ]->GetValue(),RTL_TEXTENCODING_UTF8 );
505 pElement->SetLanguageId ( language );
506 pElement->SetId(tmpStrVal);
507 pElement->SetOldRef ( oldref );
508 pElement->SetPos( pos );
511 if ( bInsert && ( nodes_localize.find( sName ) != nodes_localize.end() ) )
512 InsertL10NElement(pElement);
513 else if ( bInsert && pElement->GetChildList() ){
514 for ( size_t k = 0; k < pElement->GetChildList()->size(); k++ )
515 SearchL10NElements( (XMLParentNode*)(*pElement->GetChildList())[ k ], k);
518 break;
519 case XML_NODE_TYPE_DATA: {
521 break;
522 case XML_NODE_TYPE_COMMENT: {
524 break;
525 case XML_NODE_TYPE_DEFAULT: {
527 break;
532 /*****************************************************************************/
533 bool XMLFile::CheckExportStatus( XMLParentNode *pCur )
534 /*****************************************************************************/
536 static bool bStatusExport = true;
537 const rtl::OString LOCALIZE("localize");
538 const rtl::OString STATUS(RTL_CONSTASCII_STRINGPARAM("status"));
539 const rtl::OString PUBLISH(RTL_CONSTASCII_STRINGPARAM("PUBLISH"));
540 const rtl::OString DEPRECATED(RTL_CONSTASCII_STRINGPARAM("DEPRECATED"));
541 const rtl::OString TOPIC(RTL_CONSTASCII_STRINGPARAM("topic"));
543 bool bInsert = true;
544 if ( !pCur )
545 CheckExportStatus( this );
546 else {
547 switch( pCur->GetNodeType()) {
548 case XML_NODE_TYPE_FILE: {
549 XMLParentNode* pElement;
550 if( GetChildList()){
551 for ( size_t i = 0; i < GetChildList()->size(); i++ ){
552 pElement = (XMLParentNode*)(*GetChildList())[ i ];
553 if( pElement->GetNodeType() == XML_NODE_TYPE_ELEMENT ) CheckExportStatus( pElement );//, i);
557 break;
558 case XML_NODE_TYPE_ELEMENT: {
559 XMLElement *pElement = ( XMLElement * ) pCur;
560 rtl::OString sName(rtl::OUStringToOString(pElement->GetName(), RTL_TEXTENCODING_ASCII_US));
561 if (sName.equalsIgnoreAsciiCase(TOPIC))
563 if ( pElement->GetAttributeList())
565 for (size_t j = 0 , cnt = pElement->GetAttributeList()->size(); j < cnt && bInsert; ++j)
567 const rtl::OString tmpStr(rtl::OUStringToOString((*pElement->GetAttributeList())[j]->GetName(),
568 RTL_TEXTENCODING_UTF8));
569 if (tmpStr.equalsIgnoreAsciiCase(STATUS))
571 rtl::OString tmpStrVal(rtl::OUStringToOString( (*pElement->GetAttributeList())[j]->GetValue(),
572 RTL_TEXTENCODING_UTF8));
573 if (!tmpStrVal.equalsIgnoreAsciiCase(PUBLISH) &&
574 !tmpStrVal.equalsIgnoreAsciiCase(DEPRECATED))
576 bStatusExport = false;
583 else if ( pElement->GetChildList() )
585 for (size_t k = 0; k < pElement->GetChildList()->size(); ++k)
586 CheckExportStatus( (XMLParentNode*)(*pElement->GetChildList())[k] );
589 break;
592 return bStatusExport;
595 /*****************************************************************************/
596 sal_uInt16 XMLElement::GetNodeType()
597 /*****************************************************************************/
599 return XML_NODE_TYPE_ELEMENT;
602 /*****************************************************************************/
603 XMLElement::XMLElement(const XMLElement& obj)
604 /*****************************************************************************/
606 XMLParentNode ( obj ),
607 sElementName ( obj.sElementName ),
608 pAttributes ( NULL ),
609 project ( obj.project ),
610 filename ( obj.filename ),
611 id ( obj.id ),
612 sOldRef ( obj.sOldRef ),
613 resourceType ( obj.resourceType ),
614 languageId ( obj.languageId ),
615 nPos ( obj.nPos )
618 if ( obj.pAttributes ){
619 pAttributes = new XMLAttributeList();
620 for ( size_t i = 0; i < obj.pAttributes->size(); i++ )
621 AddAttribute( (*obj.pAttributes)[ i ]->GetName(), (*obj.pAttributes)[ i ]->GetValue() );
625 /*****************************************************************************/
626 XMLElement& XMLElement::operator=(const XMLElement& obj){
627 /*****************************************************************************/
628 if( this!=&obj ){
629 XMLParentNode::operator=(obj);
630 sElementName =obj.sElementName;
631 project =obj.project;
632 filename =obj.filename;
633 id =obj.id;
634 sOldRef =obj.sOldRef;
635 resourceType =obj.resourceType;
636 languageId =obj.languageId;
637 nPos =obj.nPos;
639 if ( pAttributes ){
640 for ( size_t i = 0; i < pAttributes->size(); i++ )
641 delete (*pAttributes)[ i ];
642 delete pAttributes;
644 if ( obj.pAttributes ){
645 pAttributes =new XMLAttributeList();
646 for ( size_t i = 0; i < obj.pAttributes->size(); i++ )
647 AddAttribute( (*obj.pAttributes)[ i ]->GetName(), (*obj.pAttributes)[ i ]->GetValue() );
650 return *this;
653 /*****************************************************************************/
654 void XMLElement::AddAttribute( const rtl::OUString &rAttribute, const rtl::OUString &rValue )
655 /*****************************************************************************/
657 if ( !pAttributes )
658 pAttributes = new XMLAttributeList();
659 pAttributes->push_back( new XMLAttribute( rAttribute, rValue ) );
662 /*****************************************************************************/
663 void XMLElement::ChangeLanguageTag( const rtl::OUString &rValue )
665 SetLanguageId(rtl::OUStringToOString(rValue, RTL_TEXTENCODING_UTF8));
666 if ( pAttributes )
668 for (size_t i = 0; i < pAttributes->size(); ++i)
670 if ( (*pAttributes)[ i ]->GetName() == "xml-lang" )
671 (*pAttributes)[ i ]->setValue(rValue);
674 XMLChildNode* pNode = NULL;
675 XMLElement* pElem = NULL;
676 XMLChildNodeList* pCList = GetChildList();
678 if( pCList != NULL )
680 for ( size_t i = 0; i < pCList->size(); i++ )
682 pNode = (*pCList)[ i ];
683 if( pNode != NULL && pNode->GetNodeType() == XML_NODE_TYPE_ELEMENT )
685 pElem = static_cast< XMLElement* >(pNode);
686 pElem->ChangeLanguageTag( rValue );
687 pElem->SetLanguageId(rtl::OUStringToOString(rValue, RTL_TEXTENCODING_UTF8));
688 pElem = NULL;
689 pNode = NULL;
692 pCList = NULL;
696 /*****************************************************************************/
697 XMLElement::~XMLElement()
698 /*****************************************************************************/
700 if ( pAttributes ) {
701 for ( size_t i = 0; i < pAttributes->size(); i++ )
702 delete (*pAttributes)[ i ];
704 delete pAttributes;
705 pAttributes = NULL;
709 /*****************************************************************************/
710 OUString XMLElement::ToOUString(){
711 /*****************************************************************************/
712 OUStringBuffer* buffer = new OUStringBuffer();
713 Print(this,*buffer,true);
714 OUString result=buffer->makeStringAndClear();
715 rtl::OUString xy(result.getStr());
716 result=OUString(xy);
717 delete buffer;
718 return result;
720 /*****************************************************************************/
721 void XMLElement::Print(XMLNode *pCur, OUStringBuffer& buffer , bool rootelement ){
722 /*****************************************************************************/
723 static const OUString XML_LANG ( "xml-lang" );
725 if(pCur!=NULL){
726 if(rootelement){
727 XMLElement *pElement = ( XMLElement * ) pCur;
728 if ( pElement->GetAttributeList()){
729 if ( pElement->GetChildList()){
730 XMLChildNode* tmp=NULL;
731 for ( size_t k = 0; k < pElement->GetChildList()->size(); k++ ){
732 tmp = (*pElement->GetChildList())[ k ];
733 Print( tmp, buffer , false);
738 else{
740 switch( pCur->GetNodeType()) {
741 case XML_NODE_TYPE_ELEMENT: {
742 XMLElement *pElement = ( XMLElement * ) pCur;
744 if( !pElement->GetName().equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("comment")) ){
745 buffer.append( OUString("\\<") );
746 buffer.append( pElement->GetName() );
747 if ( pElement->GetAttributeList()){
748 for ( size_t j = 0; j < pElement->GetAttributeList()->size(); j++ ){
750 OUString aAttrName( (*pElement->GetAttributeList())[ j ]->GetName() );
751 if( !aAttrName.equalsIgnoreAsciiCase( XML_LANG ) ) {
752 buffer.append( OUString(" ") );
753 buffer.append( aAttrName );
754 buffer.append( OUString("=") );
755 buffer.append( OUString("\\\"") );
756 buffer.append( (*pElement->GetAttributeList())[ j ]->GetValue() );
757 buffer.append( OUString("\\\"") );
761 if ( !pElement->GetChildList())
762 buffer.append( OUString("/\\>") );
763 else {
764 buffer.append( OUString("\\>") );
765 XMLChildNode* tmp=NULL;
766 for ( size_t k = 0; k < pElement->GetChildList()->size(); k++ ){
767 tmp = (*pElement->GetChildList())[ k ];
768 Print( tmp, buffer , false);
770 buffer.append( OUString("\\</") );
771 buffer.append( pElement->GetName() );
772 buffer.append( OUString("\\>") );
776 break;
777 case XML_NODE_TYPE_DATA: {
778 XMLData *pData = ( XMLData * ) pCur;
779 rtl::OUString sData = pData->GetData();
780 buffer.append( sData );
782 break;
783 case XML_NODE_TYPE_COMMENT: {
784 XMLComment *pComment = ( XMLComment * ) pCur;
785 buffer.append( OUString("<!--") );
786 buffer.append( pComment->GetComment() );
787 buffer.append( OUString("-->") );
789 break;
790 case XML_NODE_TYPE_DEFAULT: {
791 XMLDefault *pDefault = ( XMLDefault * ) pCur;
792 buffer.append( pDefault->GetDefault() );
794 break;
797 }else {
798 fprintf(stdout,"\n#+------Error: NULL Pointer in XMLELement::Print------+#\n");
799 return;
805 // class XMLData
807 /*****************************************************************************/
808 XMLData::XMLData(const XMLData& obj)
809 /*****************************************************************************/
810 : XMLChildNode( obj ),
811 sData( obj.sData ) ,
812 isNewCreated ( obj.isNewCreated ){}
814 /*****************************************************************************/
815 XMLData& XMLData::operator=(const XMLData& obj){
816 /*****************************************************************************/
817 if( this!=&obj ){
818 XMLChildNode::operator=( obj );
819 sData = obj.sData;
820 isNewCreated = obj.isNewCreated;
822 return *this;
824 /*****************************************************************************/
825 void XMLData::AddData( const rtl::OUString &rData) {
826 /*****************************************************************************/
827 sData += rData;
830 /*****************************************************************************/
831 sal_uInt16 XMLData::GetNodeType()
832 /*****************************************************************************/
834 return XML_NODE_TYPE_DATA;
838 // class XMLComment
841 /*****************************************************************************/
842 sal_uInt16 XMLComment::GetNodeType()
843 /*****************************************************************************/
845 return XML_NODE_TYPE_COMMENT;
847 /*****************************************************************************/
848 XMLComment::XMLComment(const XMLComment& obj)
849 /*****************************************************************************/
850 : XMLChildNode( obj ),
851 sComment( obj.sComment ){}
853 /*****************************************************************************/
854 XMLComment& XMLComment::operator=(const XMLComment& obj){
855 /*****************************************************************************/
856 if( this!=&obj ){
857 XMLChildNode::operator=( obj );
858 sComment = obj.sComment;
860 return *this;
864 // class XMLDefault
867 /*****************************************************************************/
868 sal_uInt16 XMLDefault::GetNodeType()
869 /*****************************************************************************/
871 return XML_NODE_TYPE_DEFAULT;
873 /*****************************************************************************/
874 XMLDefault::XMLDefault(const XMLDefault& obj)
875 /*****************************************************************************/
876 : XMLChildNode( obj ),
877 sDefault( obj.sDefault){}
879 /*****************************************************************************/
880 XMLDefault& XMLDefault::operator=(const XMLDefault& obj){
881 /*****************************************************************************/
882 if( this!=&obj ){
883 XMLChildNode::operator=( obj );
884 sDefault = obj.sDefault;
886 return *this;
891 // class SimpleXMLParser
894 #define XML_CHAR_TO_OUSTRING(x) OStringToOUString(OString(x), RTL_TEXTENCODING_UTF8)
895 #define XML_CHAR_N_TO_OUSTRING(x,n) OStringToOUString(OString(x,n), RTL_TEXTENCODING_UTF8 )
898 /*****************************************************************************/
899 SimpleXMLParser::SimpleXMLParser()
900 /*****************************************************************************/
901 : pXMLFile( NULL )
903 aParser = XML_ParserCreate( NULL );
904 XML_SetUserData( aParser, this );
905 XML_SetElementHandler( aParser, (XML_StartElementHandler) StartElementHandler, (XML_EndElementHandler) EndElementHandler );
906 XML_SetCharacterDataHandler( aParser, (XML_CharacterDataHandler) CharacterDataHandler );
907 XML_SetCommentHandler( aParser, (XML_CommentHandler) CommentHandler );
908 XML_SetDefaultHandler( aParser, (XML_DefaultHandler) DefaultHandler );
911 /*****************************************************************************/
912 SimpleXMLParser::~SimpleXMLParser()
913 /*****************************************************************************/
915 XML_ParserFree( aParser );
918 /*****************************************************************************/
919 void SimpleXMLParser::StartElementHandler(
920 void *userData, const XML_Char *name, const XML_Char **atts )
921 /*****************************************************************************/
923 (( SimpleXMLParser * ) userData )->StartElement( name, atts );
927 /*****************************************************************************/
928 void SimpleXMLParser::EndElementHandler(
929 void *userData, const XML_Char *name )
930 /*****************************************************************************/
932 (( SimpleXMLParser * ) userData )->EndElement( name );
935 /*****************************************************************************/
936 void SimpleXMLParser::CharacterDataHandler(
937 void *userData, const XML_Char *s, int len )
938 /*****************************************************************************/
940 (( SimpleXMLParser * ) userData )->CharacterData( s, len );
943 /*****************************************************************************/
944 void SimpleXMLParser::CommentHandler(
945 void *userData, const XML_Char *data )
946 /*****************************************************************************/
948 (( SimpleXMLParser * ) userData )->Comment( data );
951 /*****************************************************************************/
952 void SimpleXMLParser::DefaultHandler(
953 void *userData, const XML_Char *s, int len )
954 /*****************************************************************************/
956 (( SimpleXMLParser * ) userData )->Default( s, len );
959 /*****************************************************************************/
960 void SimpleXMLParser::StartElement(
961 const XML_Char *name, const XML_Char **atts )
962 /*****************************************************************************/
964 rtl::OUString sElementName = rtl::OUString( XML_CHAR_TO_OUSTRING( name ));
965 XMLElement *pElement = new XMLElement( sElementName, ( XMLParentNode * ) pCurNode );
966 pCurNode = pElement;
967 pCurData = NULL;
969 int i = 0;
970 while( atts[i] ) {
971 pElement->AddAttribute(
972 rtl::OUString( XML_CHAR_TO_OUSTRING( atts[ i ] )),
973 rtl::OUString( XML_CHAR_TO_OUSTRING( atts[ i + 1 ] )));
974 i += 2;
978 /*****************************************************************************/
979 void SimpleXMLParser::EndElement( const XML_Char *name )
980 /*****************************************************************************/
982 // This variable is not used at all, but the the sax C interface can't be changed
983 // To prevent warnings this dummy assignment is used
984 // +++
985 (void) name;
987 pCurNode = pCurNode->GetParent();
988 pCurData = NULL;
991 /*****************************************************************************/
992 void SimpleXMLParser::CharacterData(
993 const XML_Char *s, int len )
994 /*****************************************************************************/
996 if ( !pCurData ){
997 rtl::OUString x = XML_CHAR_N_TO_OUSTRING( s, len );
998 XMLUtil::UnQuotHTML(x);
999 pCurData = new XMLData( x , pCurNode );
1000 }else{
1001 rtl::OUString x = XML_CHAR_N_TO_OUSTRING( s, len );
1002 XMLUtil::UnQuotHTML(x);
1003 pCurData->AddData( x );
1008 /*****************************************************************************/
1009 void SimpleXMLParser::Comment(
1010 const XML_Char *data )
1011 /*****************************************************************************/
1013 pCurData = NULL;
1014 new XMLComment( rtl::OUString( XML_CHAR_TO_OUSTRING( data )), pCurNode );
1017 /*****************************************************************************/
1018 void SimpleXMLParser::Default(
1019 const XML_Char *s, int len )
1020 /*****************************************************************************/
1022 pCurData = NULL;
1023 new XMLDefault(
1024 rtl::OUString( XML_CHAR_N_TO_OUSTRING( s, len )), pCurNode );
1027 /*****************************************************************************/
1028 XMLFile *SimpleXMLParser::Execute( const rtl::OUString &rFileName, XMLFile* pXMLFileIn )
1029 /*****************************************************************************/
1031 aErrorInformation.eCode = XML_ERROR_NONE;
1032 aErrorInformation.nLine = 0;
1033 aErrorInformation.nColumn = 0;
1034 aErrorInformation.sMessage = rtl::OUString( "ERROR: Unable to open file ");
1035 aErrorInformation.sMessage += rFileName;
1037 rtl::OUString aFileURL(common::pathnameToAbsoluteUrl(rFileName));
1039 oslFileHandle h;
1040 if (osl_openFile(aFileURL.pData, &h, osl_File_OpenFlag_Read)
1041 != osl_File_E_None)
1043 return 0;
1046 sal_uInt64 s;
1047 oslFileError e = osl_getFileSize(h, &s);
1048 void * p = NULL;
1049 if (e == osl_File_E_None) {
1050 e = osl_mapFile(h, &p, s, 0, 0);
1052 if (e != osl_File_E_None) {
1053 osl_closeFile(h);
1054 return 0;
1057 pXMLFile = pXMLFileIn;
1058 pXMLFile->SetName( rFileName );
1060 pCurNode = pXMLFile;
1061 pCurData = NULL;
1063 aErrorInformation.eCode = XML_ERROR_NONE;
1064 aErrorInformation.nLine = 0;
1065 aErrorInformation.nColumn = 0;
1066 if ( !pXMLFile->GetName().isEmpty()) {
1067 aErrorInformation.sMessage = rtl::OUString( "File ");
1068 aErrorInformation.sMessage += pXMLFile->GetName();
1069 aErrorInformation.sMessage += rtl::OUString( " parsed successfully");
1071 else
1072 aErrorInformation.sMessage = rtl::OUString( "XML-File parsed successfully");
1074 if (!XML_Parse(aParser, reinterpret_cast< char * >(p), s, true))
1076 aErrorInformation.eCode = XML_GetErrorCode( aParser );
1077 aErrorInformation.nLine = XML_GetErrorLineNumber( aParser );
1078 aErrorInformation.nColumn = XML_GetErrorColumnNumber( aParser );
1080 aErrorInformation.sMessage = rtl::OUString( "ERROR: ");
1081 if ( !pXMLFile->GetName().isEmpty())
1082 aErrorInformation.sMessage += pXMLFile->GetName();
1083 else
1084 aErrorInformation.sMessage += rtl::OUString( "XML-File (");
1085 aErrorInformation.sMessage += rtl::OUString::valueOf(
1086 sal::static_int_cast< sal_Int64 >(aErrorInformation.nLine));
1087 aErrorInformation.sMessage += rtl::OUString( ",");
1088 aErrorInformation.sMessage += rtl::OUString::valueOf(
1089 sal::static_int_cast< sal_Int64 >(aErrorInformation.nColumn));
1090 aErrorInformation.sMessage += rtl::OUString( "): ");
1092 switch (aErrorInformation.eCode) {
1093 case XML_ERROR_NO_MEMORY:
1094 aErrorInformation.sMessage += rtl::OUString( "No memory");
1095 break;
1096 case XML_ERROR_SYNTAX:
1097 aErrorInformation.sMessage += rtl::OUString( "Syntax");
1098 break;
1099 case XML_ERROR_NO_ELEMENTS:
1100 aErrorInformation.sMessage += rtl::OUString( "No elements");
1101 break;
1102 case XML_ERROR_INVALID_TOKEN:
1103 aErrorInformation.sMessage += rtl::OUString( "Invalid token");
1104 break;
1105 case XML_ERROR_UNCLOSED_TOKEN:
1106 aErrorInformation.sMessage += rtl::OUString( "Unclosed token");
1107 break;
1108 case XML_ERROR_PARTIAL_CHAR:
1109 aErrorInformation.sMessage += rtl::OUString( "Partial char");
1110 break;
1111 case XML_ERROR_TAG_MISMATCH:
1112 aErrorInformation.sMessage += rtl::OUString( "Tag mismatch");
1113 break;
1114 case XML_ERROR_DUPLICATE_ATTRIBUTE:
1115 aErrorInformation.sMessage += rtl::OUString( "Dublicat attribute");
1116 break;
1117 case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
1118 aErrorInformation.sMessage += rtl::OUString( "Junk after doc element");
1119 break;
1120 case XML_ERROR_PARAM_ENTITY_REF:
1121 aErrorInformation.sMessage += rtl::OUString( "Param entity ref");
1122 break;
1123 case XML_ERROR_UNDEFINED_ENTITY:
1124 aErrorInformation.sMessage += rtl::OUString( "Undefined entity");
1125 break;
1126 case XML_ERROR_RECURSIVE_ENTITY_REF:
1127 aErrorInformation.sMessage += rtl::OUString( "Recursive entity ref");
1128 break;
1129 case XML_ERROR_ASYNC_ENTITY:
1130 aErrorInformation.sMessage += rtl::OUString( "Async_entity");
1131 break;
1132 case XML_ERROR_BAD_CHAR_REF:
1133 aErrorInformation.sMessage += rtl::OUString( "Bad char ref");
1134 break;
1135 case XML_ERROR_BINARY_ENTITY_REF:
1136 aErrorInformation.sMessage += rtl::OUString( "Binary entity");
1137 break;
1138 case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
1139 aErrorInformation.sMessage += rtl::OUString( "Attribute external entity ref");
1140 break;
1141 case XML_ERROR_MISPLACED_XML_PI:
1142 aErrorInformation.sMessage += rtl::OUString( "Misplaced xml pi");
1143 break;
1144 case XML_ERROR_UNKNOWN_ENCODING:
1145 aErrorInformation.sMessage += rtl::OUString( "Unknown encoding");
1146 break;
1147 case XML_ERROR_INCORRECT_ENCODING:
1148 aErrorInformation.sMessage += rtl::OUString( "Incorrect encoding");
1149 break;
1150 case XML_ERROR_UNCLOSED_CDATA_SECTION:
1151 aErrorInformation.sMessage += rtl::OUString( "Unclosed cdata section");
1152 break;
1153 case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
1154 aErrorInformation.sMessage += rtl::OUString( "External entity handling");
1155 break;
1156 case XML_ERROR_NOT_STANDALONE:
1157 aErrorInformation.sMessage += rtl::OUString( "Not standalone");
1158 break;
1159 case XML_ERROR_NONE:
1160 break;
1161 default:
1162 break;
1164 delete pXMLFile;
1165 pXMLFile = NULL;
1168 osl_unmapMappedFile(h, p, s);
1169 osl_closeFile(h);
1171 return pXMLFile;
1174 /*****************************************************************************/
1175 void XMLUtil::QuotHTML( rtl::OUString &rString )
1176 /*****************************************************************************/
1178 OUStringBuffer sReturn;
1179 for (sal_Int32 i = 0; i < rString.getLength(); ++i) {
1180 switch (rString[i]) {
1181 case '\\':
1182 if (i < rString.getLength()) {
1183 switch (rString[i + 1]) {
1184 case '"':
1185 case '<':
1186 case '>':
1187 case '\\':
1188 ++i;
1189 break;
1192 // fall through
1193 default:
1194 sReturn.append(rString[i]);
1195 break;
1197 case '<':
1198 sReturn.appendAscii(RTL_CONSTASCII_STRINGPARAM("&lt;"));
1199 break;
1201 case '>':
1202 sReturn.appendAscii(RTL_CONSTASCII_STRINGPARAM("&gt;"));
1203 break;
1205 case '"':
1206 sReturn.appendAscii(RTL_CONSTASCII_STRINGPARAM("&quot;"));
1207 break;
1209 case '&':
1210 if (rString.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("&amp;"), i))
1211 sReturn.append('&');
1212 else
1213 sReturn.appendAscii(RTL_CONSTASCII_STRINGPARAM("&amp;"));
1214 break;
1217 rString = sReturn.makeStringAndClear();
1220 void XMLUtil::UnQuotHTML( rtl::OUString &rString ){
1221 rtl::OStringBuffer sReturn;
1222 rtl::OString sString(rtl::OUStringToOString(rString, RTL_TEXTENCODING_UTF8));
1223 for (sal_Int32 i = 0; i != sString.getLength();) {
1224 if (sString[i] == '\\') {
1225 sReturn.append(RTL_CONSTASCII_STRINGPARAM("\\\\"));
1226 ++i;
1227 } else if (sString.match("&amp;", i)) {
1228 sReturn.append('&');
1229 i += RTL_CONSTASCII_LENGTH("&amp;");
1230 } else if (sString.match("&lt;", i)) {
1231 sReturn.append('<');
1232 i += RTL_CONSTASCII_LENGTH("&lt;");
1233 } else if (sString.match("&gt;", i)) {
1234 sReturn.append('>');
1235 i += RTL_CONSTASCII_LENGTH("&gt;");
1236 } else if (sString.match("&quot;", i)) {
1237 sReturn.append('"');
1238 i += RTL_CONSTASCII_LENGTH("&quot;");
1239 } else if (sString.match("&apos;", i)) {
1240 sReturn.append('\'');
1241 i += RTL_CONSTASCII_LENGTH("&apos;");
1242 } else {
1243 sReturn.append(sString[i]);
1244 ++i;
1247 rString = rtl::OStringToOUString(sReturn.makeStringAndClear(), RTL_TEXTENCODING_UTF8);
1250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */