[sword-cvs] icu-sword/source/samples/xml2txt ChildName.cpp,NONE,1.1 ChildName.h,NONE,1.1 DOMPrintFormatTarget.cpp,NONE,1.1 DOMPrintFormatTarget.h,NONE,1.1 DOMTreeErrorReporter.cpp,NONE,1.1 DOMTreeErrorReporter.hpp,NONE,1.1 readme.txt,NONE,1.1 xml2res.pl,NONE,1.1 xml2txt.cpp,NONE,1.1 xml2txt.dsp,NONE,1.1 xml2txt.h,NONE,1.1 xml2txt.plg,NONE,1.1

sword@www.crosswire.org sword@www.crosswire.org
Tue, 9 Sep 2003 19:42:35 -0700


Update of /usr/local/cvsroot/icu-sword/source/samples/xml2txt
In directory www:/tmp/cvs-serv19862/source/samples/xml2txt

Added Files:
	ChildName.cpp ChildName.h DOMPrintFormatTarget.cpp 
	DOMPrintFormatTarget.h DOMTreeErrorReporter.cpp 
	DOMTreeErrorReporter.hpp readme.txt xml2res.pl xml2txt.cpp 
	xml2txt.dsp xml2txt.h xml2txt.plg 
Log Message:
ICU 2.6 commit

--- NEW FILE: ChildName.cpp ---
/******************************************************************************
 * Copyright (C) 2002, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************/
#include "ChildName.h"

void ChildName ::SetName(DOMString name)
{
	Name = name;
};
void ChildName::SetNext(ChildName* next)
{
	Next = next;
};

--- NEW FILE: ChildName.h ---
/******************************************************************************
 * Copyright (C) 2002, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************/
#ifndef CHILDNAME_H_
#define CHILDNAME_H_
#include <util/PlatformUtils.hpp>
#include <util/XMLString.hpp>
#include <util/XMLUniDefs.hpp>
#include <framework/XMLFormatter.hpp>
#include <util/TranscodingException.hpp>
#include <dom/DOM_DOMException.hpp>
#include <parsers/DOMParser.hpp>
#include <dom/DOM.hpp>
#include "DOMTreeErrorReporter.hpp"

class ChildName
{
	public:
		DOMString Name;
		ChildName* Next;

		ChildName(){};

		void SetName(DOMString name);
		void SetNext(ChildName* next);
};

#endif

--- NEW FILE: DOMPrintFormatTarget.cpp ---
/******************************************************************************
 * Copyright (C) 2002, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************/
#include "DOMPrintFormatTarget.h"

DOMPrintFormatTarget::DOMPrintFormatTarget() {

};

DOMPrintFormatTarget::DOMPrintFormatTarget(char* fileName) {
	this->fileName = fileName;
}

DOMPrintFormatTarget::~DOMPrintFormatTarget() {};

void DOMPrintFormatTarget :: writeChars(const   XMLByte* const  toWrite,
                   const   unsigned int    count,
                   XMLFormatter * const formatter)
{
	ofstream ofile( fileName, ios::app);
	ofile.write((char *) toWrite, (int) count);
};

--- NEW FILE: DOMPrintFormatTarget.h ---
/******************************************************************************
 * Copyright (C) 2002, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************/
#ifndef DOMPRINTFORMATTARGET_H_
#define DOMPRINTFORMATTARGET_H_
#include "ChildName.h"
#include <fstream.h>
class DOMPrintFormatTarget : public XMLFormatTarget
{
private: 
	char* fileName;
public:
    DOMPrintFormatTarget();
	DOMPrintFormatTarget(char* fileName);
    ~DOMPrintFormatTarget();
    // -----------------------------------------------------------------------
    //  Implementations of the format target interface
    // -----------------------------------------------------------------------

    void writeChars(const   XMLByte* const  toWrite,
                    const   unsigned int    count,
                            XMLFormatter * const formatter);

private:
    // -----------------------------------------------------------------------
    //  Unimplemented methods.
    // -----------------------------------------------------------------------
    DOMPrintFormatTarget(const DOMPrintFormatTarget& other);
    void operator=(const DOMPrintFormatTarget& rhs);
};

#endif

--- NEW FILE: DOMTreeErrorReporter.cpp ---
/******************************************************************************
 * Copyright (C) 2002, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************/
// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <sax/SAXParseException.hpp>
#include "DOMTreeErrorReporter.hpp"
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include <dom/DOMString.hpp>

extern ostream& operator<<(ostream& target, const DOMString& s);

void DOMTreeErrorReporter::warning(const SAXParseException&)
{
}

void DOMTreeErrorReporter::error(const SAXParseException& toCatch)
{
    fSawErrors = true;
    cerr << "Error at file \"" << DOMString(toCatch.getSystemId())
		 << "\", line " << toCatch.getLineNumber()
		 << ", column " << toCatch.getColumnNumber()
         << "\n   Message: " << DOMString(toCatch.getMessage()) << endl;
}

void DOMTreeErrorReporter::fatalError(const SAXParseException& toCatch)
{
    fSawErrors = true;
    cerr << "Fatal Error at file \"" << DOMString(toCatch.getSystemId())
		 << "\", line " << toCatch.getLineNumber()
		 << ", column " << toCatch.getColumnNumber()
         << "\n   Message: " << DOMString(toCatch.getMessage()) << endl;
}

void DOMTreeErrorReporter::resetErrors()
{
}

--- NEW FILE: DOMTreeErrorReporter.hpp ---
/******************************************************************************
 * Copyright (C) 2002, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************/
#include <util/XercesDefs.hpp>
#include <sax/ErrorHandler.hpp>
#include <iostream.h>

class DOMTreeErrorReporter : public ErrorHandler
{
public:
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    DOMTreeErrorReporter() :
       fSawErrors(false)
    {
    }

    ~DOMTreeErrorReporter()
    {
    }

    // -----------------------------------------------------------------------
    //  Implementation of the error handler interface
    // -----------------------------------------------------------------------
    void warning(const SAXParseException& toCatch);
    void error(const SAXParseException& toCatch);
    void fatalError(const SAXParseException& toCatch);
    void resetErrors();

    // -----------------------------------------------------------------------
    //  Getter methods
    // -----------------------------------------------------------------------
    bool getSawErrors() const;

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fSawErrors
    //      This is set if we get any errors, and is queryable via a getter
    //      method. Its used by the main code to suppress output if there are
    //      errors.
    // -----------------------------------------------------------------------
    bool    fSawErrors;
};

inline bool DOMTreeErrorReporter::getSawErrors() const
{
    return fSawErrors;
}

--- NEW FILE: readme.txt ---
The xml2txt sample has been deprecated. It was a demonstration of converting ICU4C XML resource bundles into .txt resource bundles. Since it was written, the ICU4C XML resource bundle format has been depreceated, and ICU now uses XLIFF (XML Localization Interchange File Format) instead. 
--- NEW FILE: xml2res.pl ---
#/usr/bin/perl

####################################################################################
# xml2res.pl:
# This tool invokes xml2txt and genrb to produce res files from xml files
# Author: Ram Viswanadha
#        
####################################################################################
use File::Find;
use File::Basename;
use IO::File;
use Cwd;
use File::Copy;
use Getopt::Long;
use File::Path;
use File::Copy;

GetOptions(
           "--lib=s" => \$envVar,
           "--icuroot=s" => \$icuRoot,
           "--xerces=s" => \$xercesBin,
           "--xml2txt=s" => \$xml2txt,
           "--genrb=s" => \$genrb,
           "--sourcedir=s" => \$sourceDir,
           "--destdir=s" => \$destDir);
           

usage() unless defined $icuRoot;
usage() unless defined $xercesBin;
usage() unless defined $sourceDir;
usage() unless defined $destDir;
usage() unless defined $xml2txt;
usage() unless defined $genrb;

# create a temp directory and copy all the txt files there
my $tempDir = $destDir."/temp";
mkpath($tempDir);
my $prefix;

# set up environment 
if($$^O =~ /win/){
    $prefix ="";
    cmd("set PATH=%PATH%;$icuRoot/bin;$xercesBin;");
}else{
    $prefix ="$ldVar=$ICU_ROOT/source/common:$ICU_ROOT/source/i18n:$ICU_ROOT/source/tools/toolutil:$ICU_ROOT/source/data/out:$ICU_ROOT/source/data: "
}

# create list of xml files
my @list;
if (@ARGV) {
    @list = @ARGV;
    foreach (@list) { $_ .= ".xml" unless (/\.xml$/i); }
} else {
    opendir(DIR,$sourceDir);
    @list = grep{/\.xml$/} readdir(DIR);
    closedir(DIR);
}

# now convert
foreach $item (@list){
    next if($item eq "." || $item eq "..");
    texify($item);
    $txt = $item;;
    $txt =~ s/xml$/txt/i;
    resify($txt);
}

# run the xml2txt converter
sub texify{
    my $infile = shift;
    my $xml2txtExec = $xml2txt."/xml2txt";
    cmd("$prefix $xml2txtExec --sourcedir $sourceDir --destdir $tempDir $infile");
}

# run genrb 
sub resify{
    my $infile = shift;
    my $genrbExec = $genrb."/genrb";
    cmd("$prefix $genrbExec --sourcedir $tempDir --destdir $destDir --encoding UTF8 $infile");
}

#-----------------------------------------------------------------------
# Execute a command
# Param: Command
# Param: Display line, or '' to display command
sub cmd {
    my $cmd = shift;
    my $prompt = shift;
    $prompt = "Command: $cmd.." unless ($prompt);
    print $prompt;
    system($cmd);
    my $exit_value  = $? >> 8;
    #my $signal_num  = $? & 127;
    #my $dumped_core = $? & 128;
    if ($exit_value == 0) {
        print "ok\n";
    } else {
        ++$errCount;
        print "ERROR ($exit_value)\n";
        exit(1);
    }
}

#-----------------------------------------------------------------------
sub usage {
    print << "END";
Usage:
xml2res.pl 
Options:
        --lib=<environment variable for lib path> 
        --sourcedir=<directory> 
        --icuroot=<path to ICU's root directory> 
        --xerces=<path to bin directory of Xerces>
        --xml2txt=<path to xml2txt executatble>
        --genrb=<path to genrb executatble>

xml2res creates *.res file from *.xml files by invoking the respective tools
Optionally, one or more locales may be specified on the command line.
If this is done, only those locales will be processed.  If no locales
are listed, all locales are processed.

END
  exit(0);
}
--- NEW FILE: xml2txt.cpp ---
/******************************************************************************
 * Copyright (C) 2002, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************/
#include "xml2txt.h"

static bool DTDFLAG = false;
static char*                    gTxtFile;
static char*                    gXmlFile;   
static const char               *sourceDir;
static const char               *destDir;
static bool                     gDoNamespaces          = false;
static bool                     gDoSchema              = false;
static bool                     gDoCreate              = false;
static XMLCh*                   gEncodingName          = 0;
static XMLFormatter::UnRepFlags gUnRepFlags            = XMLFormatter::UnRep_CharRef;
static DOMParser::ValSchemes    gValScheme             = DOMParser::Val_Auto;
static XMLFormatter*            gFormatter             = 0;



enum
{
   HELP,
   SOURCEDIR,
   DESTDIR,
};
//#define UOPTION_TXT          UOPTION_DEF("txt", 't', UOPT_NO_ARG)
//#define UOPTION_RES          UOPTION_DEF("res", 'r', UOPT_NO_ARG)

UOption options[]={
                      UOPTION_HELP_H,
                      UOPTION_SOURCEDIR,
                      UOPTION_DESTDIR,
                  };



#ifdef XP_MAC_CONSOLE
#include <console.h>
#endif


// ---------------------------------------------------------------------------
//
//  Usage()
//
// ---------------------------------------------------------------------------
void usage() 
{
    cout << "\nUsage: XML2TXT [OPTIONS] [FILES]\n\n"
            "This program is used to convert XML files to TXT files.\n"
            "Please refer to the following options. Options are not \n"
            "case sensitive.\n"
            "Options:\n"
            "\t-s or --sourcedir   \t source directory for files followed by path, default is current directory.\n"
            "\t-d or --destdir	   \t destination directory, followed by the path, default is current directory.\n"
            "\t-h or -? or --help  \t this usage text.\n"
            "\nAttention: \n"
            "\tThe text file's encoding is the same as the source file's.\n"
            
          <<  endl;
}

int main(int argC, char* argV[])
{
    int retval = 0;
    const char* arg=NULL;

    try
    {
        XMLPlatformUtils::Initialize();
    }

    catch(const XMLException& toCatch)
    {
        cerr << "Error during Xerces-c Initialization.\n"
             << "  Exception message:"
             << DOMString(toCatch.getMessage()) << endl;
        return 1;
    }

    #ifdef XP_MAC_CONSOLE

    argC = ccommand((char***)&argV);
    #endif

    argC = u_parseArgs(argC, argV, (int32_t)(sizeof(options)/sizeof(options[0])), options);

    if(argC<0) {
        cout << "error in command line argument" << argV[-argC] << endl;    
    } 

    // Watch for special case help request
    if(argC<2 || options[HELP].doesOccur) {
        usage();
        return argC < 0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
    }

    if(options[SOURCEDIR].doesOccur) {
        sourceDir = options[SOURCEDIR].value;
    }
    else {
        #ifdef WIN32
            destDir = _getcwd(NULL, 0);
        #else
            destDir = getcwd(NULL, 0);
        #endif
    }

    if(options[DESTDIR].doesOccur) {
        destDir = options[DESTDIR].value;
    }
    else {
        #ifdef WIN32
            destDir = _getcwd(NULL, 0);
        #else
            destDir = getcwd(NULL, 0);
        #endif
    }

    for(int i = 1; i< argC; i++) {
        arg = getLongPathname(argV[i]);
    
        gXmlFile = CreateFile(arg, sourceDir);
    
        gTxtFile = CreateTxtName(arg, destDir); 
        
        
        retval = ProcessTxtFile();
    }
    XMLPlatformUtils::Terminate();
    return retval;
}



int ProcessTxtFile()
{
    int retval = 0;

    DOMParser*  parser;
    DOMTreeErrorReporter* errReporter;  
    parser = new DOMParser();
    errReporter = new DOMTreeErrorReporter();
    parser->setValidationScheme(gValScheme);
    parser->setDoNamespaces(true);
    parser->setDoSchema(gDoSchema);
    
    parser->setErrorHandler(errReporter);
    parser->setCreateEntityReferenceNodes(gDoCreate);
    parser->setToCreateXMLDeclTypeNode(true);

    //
    //  Parse the XML file, catching any XML exceptions that might propogate
    //  out of it.
    //
    bool errorsOccured = false;
    try
    {
        parser->parse(gXmlFile);
        int errorCount = parser->getErrorCount();
        if (errorCount > 0)
            errorsOccured = true;
    }

    catch (const XMLException& e)
    {
        
        
        cerr << "An error occured during parsing\n   Message: "
             << DOMString(e.getMessage()) << endl;
        errorsOccured = true;
    }


    catch (const DOM_DOMException& e)
    {
       cerr << "A DOM error occured during parsing\n   DOMException code: "
             << e.code << endl;
        errorsOccured = true;
    }

    catch (...)
    {
        cerr << "An error occured during parsing\n " << endl;
        errorsOccured = true;
    }

    if(!errorsOccured && !errReporter->getSawErrors())
    {
        DOM_Node document = parser->getDocument();
        Check(document); //if check fails, exit(0); else excute the following code
        if(DTDFLAG == false){
            cout << "DTD no assigned!" << endl;
            exit(0);
        }
    }

    // If the parse and doubt-check was successful, output the document data from the DOM tree
    if (!errorsOccured && !errReporter->getSawErrors())
    {
        DOM_Node doc = parser->getDocument();
        DOMPrintFormatTarget  *formatTarget = new DOMPrintFormatTarget(gTxtFile);
        
    

        if (gEncodingName == 0)
        {
            DOMString encNameStr("UTF-8");
            DOM_Node aNode = doc.getFirstChild();
            if (aNode.getNodeType() == DOM_Node::XML_DECL_NODE)
            {
                DOMString aStr = ((DOM_XMLDecl &)aNode).getEncoding();
                if (aStr != "")
                {
                    encNameStr = aStr;
                }
            }
            unsigned int lent = encNameStr.length();
            gEncodingName = new XMLCh[lent + 1];
            XMLString::copyNString(gEncodingName, encNameStr.rawBuffer(), lent);
            gEncodingName[lent] = 0;
        }


        try
        {
            gFormatter = new XMLFormatter(gEncodingName, formatTarget,
                                          XMLFormatter::NoEscapes, gUnRepFlags);
            ofstream ofile(gTxtFile, ios::trunc);
            cout << doc;
        }
        catch (XMLException& e)
        {
            cerr << "An error occurred during creation of output transcoder. Msg is:"
                 << endl
                 << DOMString(e.getMessage()) << endl;
            retval = 3;
        }
    delete formatTarget;
    delete gFormatter;
    }   
    delete errReporter;
    delete parser;
    parser = NULL;
    errReporter = NULL;
    delete gEncodingName;
    gEncodingName=NULL;
    return retval;
}

    

    


//----------------------------------------------------------------------------
//  double-check before DOM Tree PrintOut
//----------------------------------------------------------------------------
void Check( DOM_Node &document)
{   
    // Get the name and value out for convenience
    DOMString   nodeName = document.getNodeName(); //<tag name>, type
    DOMString   nodeValue = document.getNodeValue(); //<tag content>
    
    DOMString attributeKey, attributeVal; //(key/name)(val/filename)
    unsigned long lent = nodeValue.length();
    switch (document.getNodeType())
    {
        case DOM_Node::TEXT_NODE:
        {
            break;
        }

        case DOM_Node::PROCESSING_INSTRUCTION_NODE :
        {
          break;
        }


        case DOM_Node::DOCUMENT_NODE :
        {

            DOM_Node child = document.getFirstChild();
            while( child != 0)
            {
                Check(child);
                child = child.getNextSibling();
            }
            break;
        }

        case DOM_Node::ELEMENT_NODE :
        {
            DOM_NamedNodeMap attributes = document.getAttributes();
            int attrCount = attributes.getLength();
            int item_num=0;
            for (int i = 0; i < attrCount; i++)
            {
                DOM_Node  attribute = attributes.item(i);
                
                if(attribute.getNodeName().equals("key")||attribute.getNodeName().equals("name")){
                        attributeKey = attribute.getNodeValue();
                }
                else if(attribute.getNodeName().equals("val")||attribute.getNodeName().equals("filename")){
                    attributeVal = attribute.getNodeValue();
                    item_num = i;
                }
                else{
                    //call error report         
                    ErrorReport(document, 0);
                }
            }
            
            if(document.getParentNode().getNodeName().equals("array") && attributeKey!=NULL){
                    ErrorReport(document, 1); //ErrorType =1--the element in the array has name
                }
            else if(document.getParentNode().getNodeName().equals("table") && attributeKey==NULL){
                    ErrorReport(document, 2); //element in a table has no name
            }

            if(document.getNodeName().equals("table"))
            {
                //unsigned int Child_Num;
                if(document.hasChildNodes())
                {   
                    ChildName* cn = new ChildName();
                    cn->SetNext(NULL);
                    ChildName* head = CheckNameDuplicate(document, cn);
                    DelChildName(head);
                }
            }
            else if(document.getNodeName().equals("array")) {}
            else if(document.getNodeName().equals("resourceBundle")) {}

            else if(document.getNodeName().equals("str")||document.getNodeName().equals("importBin"))
            {
                CheckEscape(attributes, attributeVal, item_num);
            }

            else if(document.getNodeName().equals("intVector"))
            {
                DOMString ivstring;
                ivstring = CheckIntvector(attributeVal, document);
                if(ivstring !=NULL)
                    attributes.item(item_num).setNodeValue(ivstring);
            }

            else if(document.getNodeName().equals("int"))
            {
                CheckInt(attributeVal, document);
            }

            else if(document.getNodeName().equals("bin"))
            {
                CheckBin(attributeVal, document);
            }

            else if(document.getNodeName().equals("import")) {}
            else if(document.getNodeName().equals("alias")) {}
            else {
                ErrorReport(document, 6);
            }


            DOM_Node child = document.getFirstChild();
            if (child != 0)
            {
                while( child != 0)
                {
                    Check(child);
                    child = child.getNextSibling();
                }
            }
            break;
        }


        case DOM_Node::ENTITY_REFERENCE_NODE:
            {
                break;
            }


        case DOM_Node::CDATA_SECTION_NODE:
            {
            break;
        }


        case DOM_Node::COMMENT_NODE:
        {
            break;
        }


        case DOM_Node::DOCUMENT_TYPE_NODE:
        {
            DTDFLAG = true;
            break;
        }


        case DOM_Node::ENTITY_NODE:
        {
            break;
        }


        case DOM_Node::XML_DECL_NODE:
        {
            break;
        }


        default:
            cerr << "Unrecognized node type = "
                 << (long)document.getNodeType() << endl;
    }
}

void CheckEscape(DOM_NamedNodeMap attributes, DOMString attributeVal, int item_num)
{
    unsigned int len;
    char Escape[7] = {'\\', 'u', '0', '0', '2', '2', '\0'};
    len = attributeVal.length();
    DOMString fromStr;
    DOMString toStr;
    const XMLCh quote[] = {(unsigned short)0x22, (unsigned short) 0};
    if(len>0)
    {
        for(unsigned int i=0; i<len; i++)
        {
            fromStr = attributeVal.substringData (i,1);
            char* temp=fromStr.transcode();
            if(fromStr.equals(quote))
            {
                toStr.appendData(Escape);
            }
            else
                toStr.appendData(fromStr);
        }
        attributes.item(item_num).setNodeValue(toStr);
    }
}

DOMString getAttributeKey(DOM_Node CNode)
{
        DOM_NamedNodeMap attributes = CNode.getAttributes();
        int attrCount = attributes.getLength();
        DOMString attributeKey;

        for (int i = 0; i < attrCount; i++)
        {
            DOM_Node  attribute = attributes.item(i);
                
            if(attribute.getNodeName().equals("key"))
                attributeKey = attribute.getNodeValue();
        }
        return attributeKey;
}

void DelChildName(ChildName* cn)
{
    ChildName* temp = cn->Next;
    while(temp!=NULL)
    {
        delete cn;
        cn = NULL;
        cn = temp;
        temp = temp->Next;
    }
    delete cn;
}

ChildName* CheckNameDuplicate(DOM_Node document, ChildName* cn)
{
    DOM_Node CNode = document.getFirstChild();

    while(CNode!=NULL)
    {
        if(CNode.getNodeName().equals("string")||CNode.getNodeName().equals("bin")||CNode.getNodeName().equals("int")||CNode.getNodeName().equals("intvector")||CNode.getNodeName().equals("import")||CNode.getNodeName().equals("table")||CNode.getNodeName().equals("array"))
        {
            DOMString cname = getAttributeKey(CNode);
            char* string = cname.transcode();
            ChildName* temp = cn;
            while(temp->Next!=NULL)
            {
                if(cname.equals(temp->Name))
                {
                    DelChildName(cn);
                    ErrorReport(CNode, 5);   //name duplication
                }
                temp = temp ->Next; 
            }

            ChildName* childname = new ChildName();
            childname->SetName(cname);
            childname->SetNext(cn);
            cn = childname;
        }
        CNode = CNode.getNextSibling(); 
    }
    return cn;
}

unsigned int GetCNodeNum(DOM_Node document)
{
    unsigned int num=0;
    DOM_Node CNode = document.getFirstChild();
    while(CNode!=NULL)
    {
        if(CNode.getNodeName().equals("string")||CNode.getNodeName().equals("bin")||CNode.getNodeName().equals("int")||CNode.getNodeName().equals("intvector")||CNode.getNodeName().equals("import")||CNode.getNodeName().equals("table")||CNode.getNodeName().equals("array"))
            num++;
        CNode = CNode.getNextSibling(); 
    }
    return num;
}

void CheckBin(DOMString attributeVal, DOM_Node document)
{
    char *stopstring;
    char toConv[2] = {'\0', '\0'};
    char* string = attributeVal.transcode();
    int count = strlen(string);
    if(count > 0)
    {
        if((count % 2)==0)
        {
            for(int i=0; i<count; i++)
            {
                toConv[0]=string[i];
                int value = strtoul(toConv, &stopstring, 16);
                unsigned int len = stopstring-toConv;
                if(len!= strlen(toConv))
                {
                    ErrorReport(document, 4);  //invalid bin value
                }
            }
        }
        else
            ErrorReport(document, 4); //invalid bin value
    }
}


void CheckInt(DOMString attributeVal, DOM_Node document)
{
    char  *stopstring;
    char* string= attributeVal.transcode();
    long value = strtoul(string, &stopstring, 0);
    unsigned int len=stopstring-string;
    if(len!=strlen(string))
        ErrorReport(document, 3);  //invalid int value
}

DOMString CheckIntvector(DOMString attributeVal, DOM_Node document)
{
                DOMString ivstring;
                char* string ;
                if(attributeVal != NULL)
                {
                    string = attributeVal.transcode();
                    char integer[32];
                    char *stopstring;
                    int i,j;
                    int len = strlen(string);
                    int begin,end;
                    int value;
                    begin = end =0;
                    for(i = 0; i < len; i++)
                    {                   
                        if(string[i]==(char)32 && i!= (len-1)){
                            end = i+1;
                            for(j = begin; j < end; j++)
                                integer[j-begin] = string[j];
                            
                        
                            integer[end-begin]='\0';
                            ivstring.appendData(integer);
                            ivstring.appendData(",");

                            value = strtoul(integer, &stopstring, 0);
                            int l = stopstring - integer;
                            if((stopstring - integer)!=(end - begin -1))
                                ErrorReport(document, 3); //invalid int value
                            begin = end;
                        }
                    }
                    if(string[len-1]!=(char)32)
                    {
                        for(j = begin; j < len; j++)
                            integer[j-begin] = string[j];
                        integer[len-begin] = '\0';
                        ivstring.appendData(integer);

                        value = strtoul(integer, &stopstring, 0);
                        int l = stopstring - integer;
                        if((stopstring - integer)!=(len - begin))
                            ErrorReport(document, 3); 
                    }
                return ivstring;
                }
                else
                    return NULL;

}

// ---------------------------------------------------------------------------
//  ostream << DOM_Node
//
//  Stream out a DOM node, and, recursively, all of its children. 
// ---------------------------------------------------------------------------

ostream& operator<<(ostream& target, DOM_Node& toWrite)
{
    // Get the name and value out for convenience
    DOMString   nodeName = toWrite.getNodeName(); //<tag name>, type
    DOMString   nodeValue = toWrite.getNodeValue(); //<tag content>

    DOMString attributeKey, attributeVal; //(key/name)(val/filename)
    unsigned long lent = nodeValue.length();
    

    switch (toWrite.getNodeType())
    {
        case DOM_Node::TEXT_NODE:
        {
            gFormatter->formatBuf(nodeValue.rawBuffer(),
                                  lent, XMLFormatter::CharEscapes);
            break;
        }


        case DOM_Node::PROCESSING_INSTRUCTION_NODE :
        {
            break;
        }


        case DOM_Node::DOCUMENT_NODE :
        {

            DOM_Node child = toWrite.getFirstChild();
            while( child != 0)
            {
                target << child;
                child = child.getNextSibling();
            }
            break;
        }


        case DOM_Node::ELEMENT_NODE :
        {
            
            DOM_NamedNodeMap attributes = toWrite.getAttributes();
            int attrCount = attributes.getLength();
            for (int i = 0; i < attrCount; i++)
            {
                DOM_Node  attribute = attributes.item(i);
                
                if(attribute.getNodeName().equals("key")||attribute.getNodeName().equals("name")){
                    attributeKey = attribute.getNodeValue();
                }
                else if(attribute.getNodeName().equals("val")||attribute.getNodeName().equals("filename")){
                    attributeVal = attribute.getNodeValue();
                }
            }
            
            //Print Out
            if(nodeName.equals("resourceBundle"))
                *gFormatter << attributeKey;
            else 
            {
                if(nodeName.equals("bin") && attributeVal==NULL)
                    *gFormatter <<attributeKey << ":" <<  nodeName << chSpace<< "{" << chDoubleQuote <<attributeVal << chDoubleQuote; 
                else if(nodeName.equals("str"))
                    *gFormatter <<attributeKey << chSpace<< "{" << chDoubleQuote <<attributeVal << chDoubleQuote; 
                else if(nodeName.equals("intVector"))
                    *gFormatter <<attributeKey << ":" <<  "intvector" << chSpace<< "{" <<attributeVal ; 
                else if(nodeName.equals("importBin"))
                    *gFormatter <<attributeKey << ":" <<  "import" << chSpace<< "{" << chDoubleQuote <<attributeVal << chDoubleQuote ; 
                else
                    *gFormatter <<attributeKey << ":" <<  nodeName << chSpace<< "{" << attributeVal; 
            }
                
            
            attributeKey = attributeVal = NULL;
            
         
            DOM_Node child = toWrite.getFirstChild();
            if (child != 0)
            {
                while( child != 0)
                {
                    target << child;
                    child = child.getNextSibling();
                }
                if(!nodeName.equals("resourceBundle"))
                    *gFormatter << "}";
            }
            else
            {
                if(!nodeName.equals("resourceBundle"))
                    *gFormatter << "}";
            }
            break;
        }


        case DOM_Node::ENTITY_REFERENCE_NODE:
        {
                break;
        }


        case DOM_Node::CDATA_SECTION_NODE:
        {
                break;
        }


        case DOM_Node::COMMENT_NODE:
        {
            break;
        }


        case DOM_Node::DOCUMENT_TYPE_NODE:
        {
            DOM_DocumentType doctype = (DOM_DocumentType &)toWrite;
            break;
        }


        case DOM_Node::ENTITY_NODE:
        {
            break;
        }


        case DOM_Node::XML_DECL_NODE:
        {
            break;
        }


        default:
            cerr << "Unrecognized node type = " << (long)toWrite.getNodeType() << endl;
    }
    return target;
}

void ErrorReport(DOM_Node& toWrite, int ErrorType){

    DOM_NamedNodeMap attributes;
    DOM_Node attribute;
    int attrCount, i;

    cout << "\nerror occurs at:\n";
    DOMString ErrorMsg;
    while(toWrite.getParentNode()!=NULL){
    //do
    ErrorMsg.insertData(0, ")");

    attributes = toWrite.getAttributes();
    attrCount = attributes.getLength();
    
    if(attrCount!=0)
    {
        for (i = attrCount-1; i>=0; i--)
        {
            attribute = attributes.item(i);
            ErrorMsg.insertData(0, " ; ");  
            ErrorMsg.insertData(0, attribute.getNodeValue());       
        }
    }
    ErrorMsg.insertData(0, "(");
    ErrorMsg.insertData(0, toWrite.getNodeName());
    ErrorMsg.insertData(0, "==>");
    toWrite = toWrite.getParentNode();
    }
    ErrorMsg.appendData("\n");
    
    switch (ErrorType)
    {
    case 1:
        ErrorMsg.appendData("The element in the array can't have a name!\n");
        break;
    case 2:
        ErrorMsg.appendData("The element in the table should have a name!\n");
        break;
    case 3:
        ErrorMsg.appendData("Invalid integer value!\n");
        break;
    case 4:
        ErrorMsg.appendData("Invalid bin!\n");
        break;
    case 5:
        ErrorMsg.appendData("Name Duplication in the table!\n");
        break;
    case 6:
        ErrorMsg.appendData("Invalid element name! Remember to assign correct DTD file on the xml file.\n");
        break;
    }
    cout << ErrorMsg;
    exit(0);
}

char* CreateTxtName(const char* arg, const char* Dir)
{
    char* temp = CreateFile(arg, Dir);
    int len = strlen(temp);
    temp[len-1] = 't';
    temp[len-2] = 'x';
    temp[len-3] = 't';
    return temp;

    /*char drive[_MAX_DRIVE];
    char dir[_MAX_DIR];
    char fname[_MAX_FNAME];
    char ext[_MAX_EXT];
    _splitpath(gXmlFile, drive, dir, fname, ext);
    strcpy(gTxtFile, "\0");
    if (drive != NULL) {
        strcat(gTxtFile, drive);
    }
    if (dir != NULL) {
        strcat(gTxtFile, dir);
    }
    if (fname !=NULL) {
        strcat(gTxtFile, fname);
    }
    strcat(gTxtFile, "tempfile.txt");*/
}

char* CreateFile(const char* arg, const char* Dir)
{   char* temp = new char[256];
    char a[2]={'\\', '\0'};
    char* currdir;
    if(sourceDir!=NULL) {
        strcpy(temp, Dir);
        int len = strlen(temp);
        if(temp[len - 1]!='\\') 
            strcat(temp, a);
        strcat(temp, arg);
    }
    else {
        char drive[_MAX_DRIVE];
        char dir[_MAX_DIR];
        char fname[_MAX_FNAME];
        char ext[_MAX_EXT];
        _splitpath(arg, drive, dir, fname, ext);
        
        if(*drive == NULL && *dir == NULL) {
            #ifdef WIN32
            currdir = _getcwd(NULL, 0);
            #else
            currdir = getcwd(NULL, 0);
            #endif
            strcpy(temp, currdir);
            strcat(temp, a);
        }
        strcat(temp, arg);
    }
    return temp;
}


// ---------------------------------------------------------------------------
//  ostream << DOMString
//
//  Stream out a DOM string. Doing this requires that we first transcode
//  to char * form in the default code page for the system
// ---------------------------------------------------------------------------

ostream& operator<< (ostream& target, const DOMString& s)
{
    char *p = s.transcode();
    target << p;
    delete [] p;
    return target;
}


XMLFormatter& operator<< (XMLFormatter& strm, const DOMString& s)
{
    unsigned int lent = s.length();

    if (lent <= 0)
        return strm;

    XMLCh*  buf = new XMLCh[lent + 1];
    XMLString::copyNString(buf, s.rawBuffer(), lent);
    buf[lent] = 0;
    strm << buf;
    delete [] buf;
    return strm;
}



--- NEW FILE: xml2txt.dsp ---
# Microsoft Developer Studio Project File - Name="xml2txt" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Console Application" 0x0103

CFG=xml2txt - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE 
!MESSAGE NMAKE /f "xml2txt.mak".
!MESSAGE 
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE 
!MESSAGE NMAKE /f "xml2txt.mak" CFG="xml2txt - Win32 Debug"
!MESSAGE 
!MESSAGE Possible choices for configuration are:
!MESSAGE 
!MESSAGE "xml2txt - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "xml2txt - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE 

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe

!IF  "$(CFG)" == "xml2txt - Win32 Release"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386

!ELSEIF  "$(CFG)" == "xml2txt - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\include" /I "..\..\tools\toolutil" /I "C:\work\xerces-c\xerces-c-src1_6_0\src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c
# SUBTRACT CPP /YX /Yc /Yu
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 icuind.lib icuucd.lib icutud.lib xerces-c_1D.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\lib" /libpath:"C:\work\xerces-c\xerces-c-src1_6_0\Build\Win32\VC6\Debug"
# Begin Custom Build
InputPath=.\Debug\xml2txt.exe
InputName=xml2txt
SOURCE="$(InputPath)"

"..\..\..\..\bin\$(InputName).exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
	copy $(InputPath) ..\..\..\..\bin

# End Custom Build

!ENDIF 

# Begin Target

# Name "xml2txt - Win32 Release"
# Name "xml2txt - Win32 Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=.\ChildName.cpp
# End Source File
# Begin Source File

SOURCE=.\DOMPrintFormatTarget.cpp
# End Source File
# Begin Source File

SOURCE=.\DOMTreeErrorReporter.cpp
# End Source File
# Begin Source File

SOURCE=.\xml2txt.cpp
# End Source File
# End Group
# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File

SOURCE=.\ChildName.h
# End Source File
# Begin Source File

SOURCE=.\DOMPrintFormatTarget.h
# End Source File
# Begin Source File

SOURCE=.\DOMTreeErrorReporter.hpp
# End Source File
# Begin Source File

SOURCE=.\xml2txt.h
# End Source File
# End Group
# Begin Group "Resource Files"

# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# Begin Source File

SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project

--- NEW FILE: xml2txt.h ---
/******************************************************************************
 * Copyright (C) 2002, International Business Machines Corporation and
 * others. All Rights Reserved.
 ******************************************************************************/
#ifndef xml2txt_H_
#define xml2txt_H_

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef WIN32
#include <direct.h>
#else
#include <unistd.h>
#endif

#include <process.h> 
#include <errno.h> 


#include "uoptions.h"
#include "toolutil.h"
#include "ChildName.h"
#include "DOMPrintFormatTarget.h"

//#define UOPTION_TXT              UOPTION_DEF("txt", 't', UOPT_NO_ARG)
//#define UOPTION_RES              UOPTION_DEF("res", 'r', UOPT_NO_ARG)

void     usage();
void	 InitParser();
void	 recycle();
int		 ProcessTxtFile();
void ErrorReport(DOM_Node& towrite, int ErrorType);
void Check(DOM_Node &document);
ostream& operator<<(ostream& target, const DOMString& toWrite);
ostream& operator<<(ostream& target, DOM_Node& toWrite);
XMLFormatter& operator<< (XMLFormatter& strm, const DOMString& s);
char* CreateTxtName(const char* arg, const char* Dir);
char* CreateFile(const char* arg, const char* Dir);
DOMString CheckIntvector(DOMString attributeVal, DOM_Node document);
void CheckInt(DOMString attributeVal, DOM_Node document);
void CheckBin(DOMString attributeVal, DOM_Node document);
unsigned int GetCNodeNum(DOM_Node document);
ChildName* CheckNameDuplicate(DOM_Node document, ChildName* cn);
DOMString getAttributeKey(DOM_Node CNode);
void DelChildName(ChildName* cn);
void CheckEscape(DOM_NamedNodeMap attributes, DOMString attributeVal, int item_num);

#endif

--- NEW FILE: xml2txt.plg ---
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: xml2txt - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>



<h3>Results</h3>
xml2txt.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>