Hi Francesco,
Sorry for the delay.

could you submit it as a patch?
It's much easier to apply in that form (just do a "cvs diff -bu2
>sample.patch" in wxXml2\sample).

Well I am very new to CVS and SVN so I dont know how to prepare the
patch. But in any case, I moved to SVN and currently I don't have CVS
installed, so I can not execute the suggested command.

Therefore I am sending you the full modified source file. I built the
sample and tested it. It works ok: external entities are detected and
replaced correctly. There was a bug in the code I sketched in my
previous e-mail, as it only worked ok if the xml file being processed
has only one external entity defined. If it has more than one
definition, I have discovered that after a node of type
wxXML_ENTITY_REF_NODE you will find, as children, the full list of
declared external entities. So I had to modify the code to choose the
proper one. The attached code is tested and works ok.

Hope this is OK for you.

Regards,
Cecilio



2006/12/13, Francesco Montorsi <[EMAIL PROTECTED]>:
Hi Cecilio,
    sorry again for the delay...

cecilio ha scritto:
> This is just to confirm you that replacing external entities on the
> fly works.
very good!

> The following code is the modification to add to your
> sample code:
>
>     else if (node.GetType() == wxXML_ENTITY_DECL)
>     {
>         wxXml2EntityDecl* pNode = (wxXml2EntityDecl*)&node;
>         toadd += wxString::Format(_T(", NodeType=%d, Name='%s',
> SystemID='%s'\n"),
>                      node.GetType(), pNode->GetSystemID() );
>
>         // insert here the referenced xml tree
>
>             // load the referebced XML file as tree of nodes
>         wxXml2Document oDoc;
>         wxString sError;
>         wxFileName oFN(m_sMainFilename);
>         oFN.SetFullName(pNode->GetSystemID());
>         wxString sFilename = oFN.GetFullPath();
>         if (!oDoc.Load(sFilename, &sError)) {
>             wxLogMessage(_T("Error parsing file %s\nError:%s"),
> sFilename, sError);
>             return; // or continue?
>         }
>             //Process it recursively
>         wxXml2Node oRoot = oDoc.GetRoot();
>         wxString sChildTree;
>         ParseNodeAndSiblings(oRoot, sChildTree, n);
>         toadd += sChildTree;
>     }
great - nice addition to the sample; could you submit it as a patch?
It's much easier to apply in that form (just do a "cvs diff -bu2
 >sample.patch" in wxXml2\sample).


>
> Two important issues:
>
> 1. You will see global variable m_sMainFilename. This is needed
> because the external entity URL could be relative to main file. So we
> need to know the main file URL. A second issue is that in this sample
> code I am assuming that the external entity URL is just
> "filename.ext", so that it will be located at the same folder than
> main XML file.
 > This is a non-valid assuption and so, more code must be
 > inserted to compose the rigth URL.
aren't these two issues the same ?
I'd simply write:

wxFileName oFN(pNode->GetSystemID());
if (oFN.IsRelative())
     oFN.MakeAbsolute(wxPathOnly(m_sMainFilename));

> - I did not tested this code in the sample, but in my app, so maybe
> there is some bug in last line (toadd += sChildTree).
I'll look at it....

Thanks,
Francesco

////////////////////////////////////////////////////////////////////////////
// Name:        minimal.cpp
// Purpose:     Minimal wxWindows sample
// Author:      Julian Smart
// Modified by:
// Created:     04/01/98
// RCS-ID:      $Id: minimal.cpp,v 1.16 2005/02/07 13:12:41 frm Exp $
// Copyright:   (c) Julian Smart
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

// ============================================================================
// declarations
// ============================================================================

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#include "wx/xml2.h"                            // include libxml2 wrapper 
definitions
#include "wx/dtd.h"                             // include libxml2 wrapper 
definitions
#include "wx/filename.h"

#include <wx/mstream.h>


#ifdef __BORLANDC__
    #pragma hdrstop
#endif

// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWindows headers)
#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif

// ----------------------------------------------------------------------------
// resources
// ----------------------------------------------------------------------------

// the application icon (under Windows and OS/2 it is in resources and even
// though we could still include the XPM here it would be unused)
#if !defined(__WXMSW__) && !defined(__WXPM__)
    #include "mondrian.xpm"
#endif

// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------

// Define a new application type, each program should derive a class from wxApp
class MyApp : public wxApp
{
public:
    // override base class virtuals
    // ----------------------------

    // this one is called on application startup and is a good place for the app
    // initialization (doing it here and not in the ctor allows to have an error
    // return: if OnInit() returns false, the application terminates)
    virtual bool OnInit();

        int OnExit();
};

// ----------------------------------------------------------------------------
// constants    
// ----------------------------------------------------------------------------

// IDs for the controls and the menu commands
enum
{
    // menu items
    Minimal_Quit = wxID_EXIT,

    // it is important for the id corresponding to the "About" command to have
    // this standard value as otherwise it won't be handled properly under Mac
    // (where it is special and put into the "Apple" menu)
    Minimal_About = wxID_ABOUT,

        Minimal_LoadXML,                        // these were added by me
        Minimal_LoadDTD,
        Minimal_SaveSimple,
        Minimal_SaveAdv,
        Minimal_SaveDTD,
        Minimal_Valid
};

// Define a new frame type: this is going to be our main frame
class MyFrame : public wxFrame
{
public:
    // ctor(s)
    MyFrame(const wxString& title);
        ~MyFrame();

    // event handlers (these functions should _not_ be virtual)
    void OnQuit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);

        wxTextCtrl *m_text;
        
        void LoadXML(const wxString &filename);
        void LoadDTD(const wxString &filename);

        void OnLoadXML(wxCommandEvent& event);
        void OnLoadDTD(wxCommandEvent& event);
        void OnValid(wxCommandEvent& event);

        void OnSaveSimple(wxCommandEvent& event);
        void OnSaveAdv(wxCommandEvent& event);
        void OnSaveDTD(wxCommandEvent& event);

private:
    // any class wishing to process wxWindows events must use this macro
    DECLARE_EVENT_TABLE()
};

void ParseNodeAndSiblings(const wxXml2Node &node, wxString &str, int n, const 
wxString &filename);

// ----------------------------------------------------------------------------
// event tables and other macros for wxWindows
// ----------------------------------------------------------------------------

// the event tables connect the wxWindows events with the functions (event
// handlers) which process them. It can be also done at run-time, but for the
// simple menu events like this the static method is much simpler.
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_MENU(Minimal_Quit,  MyFrame::OnQuit)
    EVT_MENU(Minimal_About, MyFrame::OnAbout)

    EVT_MENU(Minimal_LoadXML, MyFrame::OnLoadXML)
        EVT_MENU(Minimal_LoadDTD, MyFrame::OnLoadDTD)
    EVT_MENU(Minimal_SaveSimple, MyFrame::OnSaveSimple)
        EVT_MENU(Minimal_SaveAdv, MyFrame::OnSaveAdv)
        EVT_MENU(Minimal_SaveDTD, MyFrame::OnSaveDTD)
    EVT_MENU(Minimal_Valid, MyFrame::OnValid)
END_EVENT_TABLE()

// Create a new application object: this macro will allow wxWindows to create
// the application object during program execution (it's better than using a
// static object for many reasons) and also implements the accessor function
// wxGetApp() which will return the reference of the right type (i.e. MyApp and
// not wxApp)
IMPLEMENT_APP(MyApp)

// ============================================================================
// implementation
// ============================================================================

// first of all, decide if we can use the system...
#if defined(__VISUALC__)
        #define mcDETECT_MEMORY_LEAKS
#endif


#ifdef mcDETECT_MEMORY_LEAKS

        // "crtdbg.h" is included only with MSVC++ and Borland, I think...
        // "stackwalker.h" instead, contains a set of stack walker functions
        // created by Jochen Kalmbach (thanks !!!) which allow to read the
        // intercept unhandled exceptions and memory-leaks. 
        // To be used, the file must be part of the project; this is why
        // it's contained (with its CPP counterpart) in the folder of this
        // test program. Anyway,  you can find it also online at:
        //     http://www.codeproject.com/tools/leakfinder.asp
        #include <crtdbg.h>

        // define some useful macros
        #define new                 new(_NORMAL_BLOCK, THIS_FILE, __LINE__)
        #define mcDUMP_ON_EXIT          { _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF 
| _CRTDBG_ALLOC_MEM_DF); }

        
        #undef THIS_FILE
        static char THIS_FILE[] = __FILE__;


        // this little class is used to access Stackwalker functions
        // without changing a line of code...
        class mcLeakDetector {

        public:
                mcLeakDetector() { mcDUMP_ON_EXIT; }
                ~mcLeakDetector() {}
        };

        // ...infact, instancing a STATIC mcLeakDetector class, we
        // can start memory-leak detection at the very beginning of
        // the program (when the main() or winmain() has not been
        // called yet, that is, when the framework is creating the
        // static variables of the program) and end it at the very
        // end of the program (when, after the main() or winmain(),
        // the framework removes the static variables).
        static mcLeakDetector detector;

#endif




// ----------------------------------------------------------------------------
// the application class
// ----------------------------------------------------------------------------

// wxT('Main program') equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
    // create the main application window
    MyFrame *frame = new MyFrame(_T("Minimal wxWindows App"));

#if 1
        // create an useful log window
        wxLogWindow *pwindow = new wxLogWindow(frame, wxT("log"));
        pwindow->GetFrame()->Move(50, 50+350);
        pwindow->GetFrame()->SetSize(800, 300);

    // and show it (the frames, unlike simple controls, are not shown when
    // created initially)
    frame->Show(true);
#endif


        //wxXml2::Init();


    // success: wxApp::OnRun() will be called which will enter the main message
    // loop and the application will run. If we returned false here, the
    // application would exit immediately.
    return true;
}


int MyApp::OnExit()
{
        //wxXml2::Cleanup();
        return 0;
}


// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------

// frame constructor
MyFrame::MyFrame(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title, wxPoint(50, 50), wxSize(500, 300))
{
    // set the frame icon
    SetIcon(wxICON(mondrian));

#if 1
        // create the wxTextCtrl where the file structure is shown
        m_text = new wxTextCtrl(this, -1, 
                wxT("This program will provide some examples about the three 
main operations ")
                wxT("it provides on XML files:\n\n")
                wxT("\t- Loading: wxXml2 allows you to load any XML file 
including DTDs.\n")
                wxT("\t- Editing: wxXml2 allows you to create, edit, manipulate 
any XML file.\n")
                wxT("\t- Saving: wxXml2 can saves XML trees or DTDs to memory 
buffers or to files."), 
                wxDefaultPosition, wxDefaultSize, wxTE_READONLY | 
wxTE_MULTILINE);
        m_text->SetBackgroundColour(*wxWHITE);
#endif

#if wxUSE_MENUS
    // create a menu bar
    wxMenu *menuFile = new wxMenu;

    // the "About" item should be in the help menu
    wxMenu *helpMenu = new wxMenu;
    helpMenu->Append(Minimal_About, _T("&About...\tF1"), _T("Show about 
dialog"));

    menuFile->Append(Minimal_LoadXML, _T("Load XML..."), _T("Loads the given 
file and tries to parse it..."));
        menuFile->Append(Minimal_LoadDTD, _T("Load DTD..."), _T("Loads the 
given file and tries to parse it..."));
        menuFile->AppendSeparator();
    menuFile->Append(Minimal_SaveSimple, _T("Save a simple HTML file"), 
_T("Creates a sample HTML file and saves it in the given location."));  
        menuFile->Append(Minimal_SaveAdv, _T("Save an advanced XHTML file"), 
_T("Creates a sample XHTML file and saves it in the given location."));    
        menuFile->Append(Minimal_SaveDTD, _T("Save a DTD file"), _T("Creates a 
sample DTD file and saves it in the given location."));  
        menuFile->AppendSeparator();
        menuFile->Append(Minimal_Valid, _T("Validate against DTD"), 
_T("Validates an XML file against a DTD."));        
        menuFile->AppendSeparator();
    menuFile->Append(Minimal_Quit, _T("E&xit\tAlt-X"), _T("Quit this 
program"));        

    // now append the freshly created menu to the menu bar...
    wxMenuBar *menuBar = new wxMenuBar();
    menuBar->Append(menuFile, _T("&File"));
    menuBar->Append(helpMenu, _T("&Help"));

    // ... and attach this menu bar to the frame
    SetMenuBar(menuBar);
#endif // wxUSE_MENUS

#if wxUSE_STATUSBAR
    // create a status bar just for fun (by default with 1 pane only)
    CreateStatusBar(2);
    SetStatusText(_T("Welcome to wxWindows!"));
#endif // wxUSE_STATUSBAR
}

MyFrame::~MyFrame()
{
}



// event handlers

void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    // true is to force the frame to close
    Close(true);
}

void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
    wxString msg;
    msg.Printf( wxT("This is a little demonstration of wxXml2 wrappers for 
libxml2.\n\n")
                                wxT("They are based on original Vaclav Slavik's 
design but they\n")
                                wxT("use libxml2 (which is a widely-used, 
powerful cross-platform\n")
                                wxT("library) instead of EXPAT.\n\n")
                                wxT("The classes were rewritten by Francesco 
Montorsi ([EMAIL PROTECTED])\n")
                                wxT("and this sample is a modified version of 
the minimal sample of wxWidgets.\n\n")
                                wxT("This sample program was compiled with 
libxml2 version %s."),
                                        wxXml2::GetLibxml2Version().c_str());

    wxMessageBox(msg, _T("About Minimal"), wxOK | wxICON_INFORMATION, this);
}



#define STEP                    4


// helper recursive function: THIS IS ONLY A "DIDACTIVE" EXAMPLE OF A
// RECURSIVE FUNCTION WHICH CAN BE USED TO WALK AN XML TREE... 
// IF YOU JUST NEED TO OUTPUT THE CONTENTS OF AN XML TREE YOU CAN USE
// THE wxXml2Document::Save FUNCTION ON A wxMemoryOutputStream AS
// MyFrame::LoadDTD DOES TO SHOW TO THE USER THE STRUCTURE OF AN XML DTD.
void ParseNode(const wxXml2Node &node, wxString &str, int n, const wxString 
&filename)
{
    static bool m_fExtEntity=false;             //processing an external entity
    static wxString m_sExtEntityName;           // the anem of the external 
entity
    
    if (node == wxXml2EmptyNode) return;
        wxLogDebug(wxT("ParseNode - parsing [%s]"), node.GetName().c_str());
        wxString toadd, spaces(wxT(' '), n);

        // concatenate the name of this node
        toadd = node.GetName();
                
        // if this is a text node, then add also the contents...
        if (node.GetType() == wxXML_TEXT_NODE ||
                node.GetType() == wxXML_COMMENT_NODE || 
                node.GetType() == wxXML_CDATA_SECTION_NODE) {

                wxString content = node.GetContent();
                if (content.Last() == wxT('\n')) content.RemoveLast();
                if (content.GetChar(0) == wxT('\n')) content.Remove(0, 1);

                // a little exception: libxml2 when loading a document creates a
                // lot of text nodes containing just a simple \n;
                // in this cases, just show "[null]"
                wxString tmp = content.Trim();
                if (tmp.IsEmpty())
                        toadd += wxT("node: [null]");
                else 
                        toadd += wxT("node: ") + content;

    }
    else if (node.GetType() == wxXML_ENTITY_REF_NODE)
    {
        //A reference to an entity. It is like a text node, but this node 
contains 
        //only an "entity". Entities are strings like: &amp; or &quot; or &lt; 
....
        //It must have an wxXML_ENTITY_DECL child
        toadd += wxString::Format(_T(", Reference to external entity &%s;"), 
node.GetName());
        // Save the name of the node
        m_fExtEntity = true;
        m_sExtEntityName = node.GetName();
    }
    else if (node.GetType() == wxXML_ENTITY_DECL)
    {
        //As children of an external reference node we will find the list of 
all declared
        //external entities, a node per entity. The first one will be the one 
corresponding
        //to the previously found wxXML_ENTITY_REF_NODE. 
        wxXml2EntityDecl* pNode = (wxXml2EntityDecl*)&node;
        toadd += wxString::Format(_T(", Entity declaration, name='%s', 
SystemID='%s'\n"),
                    node.GetName(), pNode->GetSystemID() );

        // if this decalarion is the taht corresponds to the refeneced external 
entity
        // insert here the referenced xml tree
        if (m_fExtEntity &&  m_sExtEntityName == node.GetName())
        {
            // load the referenced XML file as tree of nodes

            wxXml2Document oDoc;
            wxString sError;
            //TODO:
            //In this sample I am assuming that the external entity URL is just
            //"filename.ext", that is, it is located at the same folder than
            //main XML file.
            //In general, this is a non-valid assuption and so, more code must 
be
            //inserted to compose the rigth URL.
            //----------------------------------------------
            wxFileName oFN(filename);
            oFN.SetFullName(pNode->GetSystemID());
            wxString sFilename = oFN.GetFullPath();
            if (!oDoc.Load(sFilename, &sError)) {
                wxLogMessage(_T("Error parsing file %s\nError:%s"),
                            sFilename, sError);
                return; // or continue?
            }
            //Process it recursively
            m_fExtEntity = false;
            m_sExtEntityName = wxEmptyString;

            wxXml2Node oRoot = oDoc.GetRoot();
            toadd += spaces;
            toadd += wxString::Format(_T("Inserting and processing file %s\n"), 
sFilename);
            toadd += spaces + _T("------------------------------------\n");
            wxString sChildTree;
            ParseNodeAndSiblings(oRoot, sChildTree, n, sFilename);
            toadd += sChildTree;
            toadd += spaces + _T("------------------------------------\n");
            toadd += spaces + _T("Returning to previous file\n");
            toadd += spaces + _T("------------------------------------\n");
        }
    }
    else {              // if it's not a text node, then add the properties...
                wxXml2Property prop(node.GetProperties());
                while (prop != wxXml2EmptyProperty) {

                        toadd += wxT(" ") + prop.GetName() + wxT("=");
                        toadd += prop.GetValue();

                        prop = prop.GetNext();
                }
        }
                
        str += spaces;

//#define SHOW_ANNOYING_NEWLINES
#ifdef SHOW_ANNOYING_NEWLINES   

        // text nodes with newlines and/or spaces will be shown as [null]
        str += toadd;
#else

        // text nodes with newlines won't be shown at all
        if (toadd != wxT("textnode: [null]")) str += toadd;
#endif

        // go one line down
        str += wxT("\n");

        // do we must add the close tag ?
        bool bClose = FALSE;

        // and then, a step more indented, its children
        wxXml2Node child(node.GetFirstChild());
        while (child != wxXml2EmptyNode) {

                ParseNode(child, str, n+STEP, filename);
                child = child.GetNext();

                // add a close tag because at least one child is present...
                bClose = TRUE;
        }

        if (bClose) str += wxString(wxT(' '), n) + wxT("/") + node.GetName() + 
wxT("\n");
}

// another helper function
void ParseNodeAndSiblings(const wxXml2Node &node, wxString &str, int n, const 
wxString &filename)
{
        wxXml2Node curr(node);

        do {
                ParseNode(curr, str, n, filename);
                curr = curr.GetNext();
        } while (curr != wxXml2EmptyNode);
}




void MyFrame::LoadXML(const wxString &filename)
{
    wxXml2Document doc;
        wxString err;

        // parse the file
        if (!doc.Load(filename, &err)) {
                wxMessageBox(wxString::Format(
                        wxT("Couldn't parse the file you chose:\n%s"), 
err.c_str()), wxT("Error"));
                return;
        }

        // show the wxXml2Node tree in a simple format...
        wxString tree;
        wxXml2Node root = doc.GetRoot();
        int indent = 3;
        tree.Alloc(1024);

        // show the DTD declaration, if present
        wxXml2DTD dtd(doc.GetDTD());
        if (dtd != wxXml2EmptyDTD) {
                tree += wxT("DTD name=") + dtd.GetName();

                if (dtd.IsPublicSubset()) 
                        tree += wxT(" PUBLIC externalID=") + 
dtd.GetExternalID() +
                                wxT(" externalURI=") + dtd.GetExternalURI() + 
wxT("\n\n");

                if (dtd.IsSystemSubset()) 
                        tree += wxT(" SYSTEM systemID=") + dtd.GetSystemID() + 
wxT("\n\n");
        }

        // get a string with the tree structure...
        ParseNodeAndSiblings(root, tree, indent, filename);

        // show it to the user  
        m_text->SetValue(tree);

        // cleanup
        dtd.DestroyIfUnlinked();
        root.DestroyIfUnlinked();
        doc.DestroyIfUnlinked();
}

void MyFrame::LoadDTD(const wxString &filename)
{
    wxXml2DTD doc;
        wxString err;

        // parse the file
        if (!doc.Load(filename, &err)) {
                wxMessageBox(wxString::Format(
                        wxT("Couldn't parse the file you chose:\n%s"), 
err.c_str()), wxT("Error"));
                return;
        }

        // show the wxXml2DTD tree in a simple format...
        wxStringOutputStream stream;

        // we won't use the ParseNodeAndSiblings because it requires
        // wxXml2Nodes to parse: here we have instead wxXml2ElemDecl,
        // wxXml2AttrDecl... node types.
        doc.Save(stream);
        m_text->SetValue(stream.GetStr());

        doc.DestroyIfUnlinked();
}

void MyFrame::OnLoadXML(wxCommandEvent& WXUNUSED(event))
{
        // ask the user which file we must load...
        wxFileDialog fd(this, wxT("Choose the XML file to load"), wxT(""), 
wxT(""), 
                wxT("XML and HTML files|*.xml;*.html;*.xhtml|All files|*.*"), 
wxOPEN);
        if (fd.ShowModal() == wxID_CANCEL)
                return;

        LoadXML(fd.GetPath());
}

void MyFrame::OnLoadDTD(wxCommandEvent& WXUNUSED(event))
{
        // ask the user which file we must load...
        wxFileDialog fd(this, wxT("Choose the DTD to load"), wxT(""), wxT(""), 
                wxT("DTD files|*.dtd|All files|*.*"), wxOPEN);
        if (fd.ShowModal() == wxID_CANCEL)
                return;

        LoadDTD(fd.GetPath());
}

void MyFrame::OnSaveSimple(wxCommandEvent& WXUNUSED(event))
{
    wxXml2Document doc;
        wxString err;

        // ask the user where we must save
        wxFileDialog fd(this, wxT("Save simple HTML example file as..."), 
wxT(""), wxT(""), 
                wxT("XML and HTML files|*.xml;*.html;*.xhtml|All files|*.*"),
                wxSAVE | wxOVERWRITE_PROMPT );
        if (fd.ShowModal() == wxID_CANCEL)
                return;

        // create an XML version 1.0
        doc.Create();

        // create the HTML header if required
        wxXml2Node html;
        html.CreateRoot(doc, wxT("html"));

        // set HTML header:
        //    <html lang="en">
        //
        html.AddProperty(wxT("lang"), wxT("en"));

        // add the head, title & body tags:
        //   <HEAD><TITLE> [title] </TITLE></HEAD>
        //   <BODY></BODY>
        //
        html.AddContainerChild(wxT("head"));
        html.Get(wxT("head")).AddTextChild(wxT("title"), wxT("Hi! I'm a sample 
HTML file"));
        wxXml2Node body = html.AddContainerChild(wxT("body"));

        // and a comment:
        //    <!-- [sample comment] -->.
        //
        body.AddCommentChild(
                wxT(" This is a dummy comment "));

        // also add a simple paragraph... <P>text</P>
        body.AddTextChild(wxT("p"),
                wxT(" HTML exported by wxXml2 wrappers for libxml2 - ") \
                wxT(" write to [EMAIL PROTECTED] if you encounter any ") \
                wxT(" problem or if you want to give suggestions or advices. 
"));

        // now, save the file where the user choose
        if (doc.Save(fd.GetPath())) {
                
                int ret = wxMessageBox(wxT("File correctly saved. Do you want 
to load it ?"), 
                        wxT("Question"), wxYES_NO | wxICON_QUESTION);
                
                if (ret == wxYES) LoadXML(fd.GetPath());

        } else {

                wxMessageBox(wxT("File could not be correctly saved !!!"), 
                                        wxT("Error"), wxOK | wxICON_ERROR);
        }

        html.DestroyIfUnlinked();
        body.DestroyIfUnlinked();
        doc.DestroyIfUnlinked();
}

void MyFrame::OnSaveAdv(wxCommandEvent &)
{
    wxXml2Document doc;
        wxString err;

        // ask the user where we must save
        wxFileDialog fd(this, wxT("Save advanced XHTML example file as..."), 
wxT(""), wxT(""), 
                wxT("XML and HTML files|*.xml;*.html;*.xhtml|All files|*.*"),
                wxSAVE | wxOVERWRITE_PROMPT );
        if (fd.ShowModal() == wxID_CANCEL)
                return;

        // create an XML version 1.0
        doc.Create();

        // create the HTML header if required
        wxXml2Node root;
        root.CreateRoot(doc, wxT("advanced_sample"));
        
        // create a MathML DTD and set it for this doc
        doc.SetMathMLDTD();

        // create a CDATA node  
        root.AddCDATAChild(wxT("my cdata block: this text is not parsed and it 
can ")
                wxT("contain any special character like <>'\",! except for the 
characters ")
                wxT("] ] > in sequence without spaces since they mark the end 
of this node"));
        
        // create a PI node: even if we create it here, it will be automatically
        // linked at the beginning of the document...
        root.AddPIChild(wxT("xml-stylesheet"), 
                wxT("type=\"text/xsl\" 
href=\"http://www.w3.org/Math/XSL/mathml.xsl\"";));

        // create a node containing a reference to an entity:
        // if everything works good, it will be recognized and embedded into
        // a wxXML_REFERENCE_NODE by wxXml2
        root.AddTextChild(wxT("refnode"), wxT("&copy;"));

#if wxUSE_UNICODE
        // then, do a little check for Unicode
        root.AddCommentChild(
                wxT("In the followig text child, some non-ANSI (i.e. Unicode) 
characters are used; ")
                wxT("If you see a greek ALPHA, BETA and GAMMA characters, it 
means that you are ")
                wxT("using a viewer which supports the Unicode standard."));

        wxString greekstring = wxT("\x3B1\x3B2\x3B3");
        root.AddTextChild(wxT("textchild"), greekstring);
#endif

        // create some simple nodes just to highlight the indentation feature 
used below...
        root.AddContainerChild(wxT("mydata"));
        root.Get(wxT("mydata")).AddContainerChild(wxT("mysubdata"));
        
root.Get(wxT("mydata")).Get(wxT("mysubdata")).AddTextChild(wxT("subdata1"), 
wxT("mytext"));
        
root.Get(wxT("mydata")).Get(wxT("mysubdata")).AddTextChild(wxT("subdata2"), 
wxT("mytext"));

        // let's test the Encapsulate function
        root.Get(wxT("mydata")).AddContainerChild(wxT("mysubdata3"));
        
root.Get(wxT("mydata")).Get(wxT("mysubdata3")).Encapsulate(wxT("mysubdata2"));
        
root.Get(wxT("mydata")).Get(wxT("mysubdata2")).Get(wxT("mysubdata3")).AddTextChild(wxT("subdata2"),
 wxT("mytext"));

        // now, save the file where the user choose
        if (doc.Save(fd.GetPath(), wxT("utf8"), 
                wxXML2DOC_USE_NATIVE_NEWLINES | wxXML2DOC_USE_INDENTATION)) {
                
                int ret = wxMessageBox(wxT("File correctly saved. Do you want 
to load it ?"), 
                        wxT("Question"), wxYES_NO | wxICON_QUESTION);
                
                if (ret == wxYES) LoadXML(fd.GetPath());

        } else {

                wxMessageBox(wxT("File could not be correctly saved !!!"), 
                                        wxT("Error"), wxOK | wxICON_ERROR);
        }

        root.DestroyIfUnlinked();
        doc.DestroyIfUnlinked();
}

void MyFrame::OnSaveDTD(wxCommandEvent &)
{
    wxXml2DTD doc;
        wxString err;

        // ask the user where we must save
        wxFileDialog fd(this, wxT("Save DTD example file as..."), wxT(""), 
wxT(""), 
                wxT("DTD files|*.dtd|All files|*.*"),
                wxSAVE | wxOVERWRITE_PROMPT );
        if (fd.ShowModal() == wxID_CANCEL)
                return;

        // create the DTD document:
        // NOTE: THE WXXML2 APIs FOR DTD CREATION ARE NOT VERY EXTENDED:
        //       THIS IS BECAUSE USUALLY DTD ARE NOT CREATED FROM A PROGRAM:
        //       USUALLY THEY ARE WRITTEN BY HAND AND THE PROGRAMS USE THEM
        //       TO VALIDATE XML DOCUMENTS.
        //       IF YOU NEED AN EXTENSION OF THESE FUNCTIONS, PLEASE CONTACT 
ME...
        doc.Create(wxXml2EmptyDoc, wxT("mydtd"), wxT("none"), wxT("none"));

        // create an element declaration and set the root
        // some errors have been experienced with some libxml2 versions 
previous to 2.6.16
        // (which is the one I use): unfortunately I haven't time to dig into 
these ones...
        wxXml2ElemContent content(wxT("myelement"), 
wxXML_ELEMENT_CONTENT_PCDATA);
        doc.AddElemDecl(wxT("myelement"), wxXML_ELEMENT_TYPE_ELEMENT, content); 

        wxXml2ElemContent content2(wxT("myelement2"), 
wxXML_ELEMENT_CONTENT_ELEMENT, wxXML_ELEMENT_CONTENT_MULT);
        doc.AddElemDecl(wxT("myelement2"), wxXML_ELEMENT_TYPE_ELEMENT, 
content2);

        wxXml2Enumeration values(wxT("text|link"));
        doc.AddAttrDecl(wxT("mydata"), wxT("type"), wxXml2EmptyNamespace,
                                        wxXML_ATTRIBUTE_ENUMERATION, 
wxXML_ATTRIBUTE_REQUIRED,
                                        wxT("default"), values);

        wxXml2Enumeration values2(values);
        doc.AddAttrDecl(wxT("mydata"), wxT("data"), wxXml2EmptyNamespace,
                                        wxXML_ATTRIBUTE_ENUMERATION, 
wxXML_ATTRIBUTE_REQUIRED,
                                        wxT("default"), values2);
        
        doc.AddEntityDecl(wxT("myentity"), wxXML_INTERNAL_GENERAL_ENTITY, 
                                                wxT(""), wxT(""), 
wxT("mycontent"));


        // now, save the file where the user choose
        if (doc.Save(fd.GetPath())) {
                
                int ret = wxMessageBox(wxT("File correctly saved. Do you want 
to load it ?"), 
                        wxT("Question"), wxYES_NO | wxICON_QUESTION);
                
                if (ret == wxYES) LoadDTD(fd.GetPath());

        } else {

                wxMessageBox(wxT("File could not be correctly saved !!!"), 
                                        wxT("Error"), wxOK | wxICON_ERROR);
        }
        
        doc.DestroyIfUnlinked();
}

void MyFrame::OnValid(wxCommandEvent &)
{
        // ask the user which file we must load...
        wxFileDialog fd(this, wxT("Choose the XML file to validate"), wxT(""), 
wxT(""), 
                wxT("XML and HTML files|*.xml;*.html;*.xhtml|All files|*.*"), 
wxOPEN);
        if (fd.ShowModal() == wxID_CANCEL)
                return;
        
        // try to do everything
    wxXml2Document doc;
        wxString err;

        // parse the file
        if (!doc.Load(fd.GetPath(), &err)) {
                wxMessageBox(wxString::Format(
                        wxT("Couldn't parse the file you chose:\n%s"), 
err.c_str()), wxT("Error"));
                return;
        }

        wxXml2DTD dtd(doc.GetDTD());
        if (dtd == wxXml2EmptyDTD) {    // if it misses a DTD...
                
                // ...ask the user which DTD we must load...
                wxFileDialog dlg(this, wxT("Choose the DTD to use"), wxT(""), 
wxT(""), 
                        wxT("DTD files|*.dtd|All files|*.*"), wxOPEN);
                if (dlg.ShowModal() == wxID_CANCEL)
                        return;
                
                // load the DTD
                wxXml2DTD dtd;
                if (!dtd.Load(dlg.GetPath(), &err)) {

                        wxMessageBox(wxT("Couldn't load that DTD:\n") + err, 
                                        wxT("Load failed"), wxOK | 
wxICON_ERROR);
                        return;
                }

                // and set it for our doc
                doc.SetDTD(dtd);
        
        } else if (dtd.IsExternalReference()) { // if it's external

                // load it
                if (!dtd.LoadFullDTD(&err)) {

                        wxMessageBox(wxT("Couldn't load that DTD:\n") + err, 
                                        wxT("Load failed"), wxOK | 
wxICON_ERROR);
                        return;
                }

        } else {

                wxASSERT(dtd.IsOk());
        }
        
        // validate the document using the DTD it now has embedded
        if (!doc.IsDTDValid(&err, TRUE)) {
                wxMessageBox(wxT("The document is not valid for the given 
DTD:\n\n") + err, 
                        wxT("Validation failed"), wxOK | wxICON_ERROR);
                return;
        }

        wxMessageBox(wxT("The document is valid for the given DTD !!"), 
                wxT("Validation successful"), wxOK | wxICON_EXCLAMATION);
        doc.DestroyIfUnlinked();
}


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
wxCode-users mailing list
wxCode-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wxcode-users

Reply via email to