xml.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 770 行 · 第 1/2 页
CPP
770 行
/////////////////////////////////////////////////////////////////////////////
// Name: xml.cpp
// Purpose: wxXmlDocument - XML parser & data holder class
// Author: Vaclav Slavik
// Created: 2000/03/05
// RCS-ID: $Id: xml.cpp,v 1.15.2.1 2005/12/18 14:55:42 VZ Exp $
// Copyright: (c) 2000 Vaclav Slavik
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "xml.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "wx/xml/xml.h"
#if wxUSE_XML
#include "wx/wfstream.h"
#include "wx/datstrm.h"
#include "wx/zstream.h"
#include "wx/log.h"
#include "wx/intl.h"
#include "wx/strconv.h"
#include "expat.h" // from Expat
// DLL options compatibility check:
#include "wx/app.h"
WX_CHECK_BUILD_OPTIONS("wxXML")
//-----------------------------------------------------------------------------
// wxXmlNode
//-----------------------------------------------------------------------------
wxXmlNode::wxXmlNode(wxXmlNode *parent,wxXmlNodeType type,
const wxString& name, const wxString& content,
wxXmlProperty *props, wxXmlNode *next)
: m_type(type), m_name(name), m_content(content),
m_properties(props), m_parent(parent),
m_children(NULL), m_next(next)
{
if (m_parent)
{
if (m_parent->m_children)
{
m_next = m_parent->m_children;
m_parent->m_children = this;
}
else
m_parent->m_children = this;
}
}
wxXmlNode::wxXmlNode(wxXmlNodeType type, const wxString& name,
const wxString& content)
: m_type(type), m_name(name), m_content(content),
m_properties(NULL), m_parent(NULL),
m_children(NULL), m_next(NULL)
{}
wxXmlNode::wxXmlNode(const wxXmlNode& node)
{
m_next = NULL;
m_parent = NULL;
DoCopy(node);
}
wxXmlNode::~wxXmlNode()
{
wxXmlNode *c, *c2;
for (c = m_children; c; c = c2)
{
c2 = c->m_next;
delete c;
}
wxXmlProperty *p, *p2;
for (p = m_properties; p; p = p2)
{
p2 = p->GetNext();
delete p;
}
}
wxXmlNode& wxXmlNode::operator=(const wxXmlNode& node)
{
wxDELETE(m_properties);
wxDELETE(m_children);
DoCopy(node);
return *this;
}
void wxXmlNode::DoCopy(const wxXmlNode& node)
{
m_type = node.m_type;
m_name = node.m_name;
m_content = node.m_content;
m_children = NULL;
wxXmlNode *n = node.m_children;
while (n)
{
AddChild(new wxXmlNode(*n));
n = n->GetNext();
}
m_properties = NULL;
wxXmlProperty *p = node.m_properties;
while (p)
{
AddProperty(p->GetName(), p->GetValue());
p = p->GetNext();
}
}
bool wxXmlNode::HasProp(const wxString& propName) const
{
wxXmlProperty *prop = GetProperties();
while (prop)
{
if (prop->GetName() == propName) return true;
prop = prop->GetNext();
}
return false;
}
bool wxXmlNode::GetPropVal(const wxString& propName, wxString *value) const
{
wxXmlProperty *prop = GetProperties();
while (prop)
{
if (prop->GetName() == propName)
{
*value = prop->GetValue();
return true;
}
prop = prop->GetNext();
}
return false;
}
wxString wxXmlNode::GetPropVal(const wxString& propName, const wxString& defaultVal) const
{
wxString tmp;
if (GetPropVal(propName, &tmp))
return tmp;
return defaultVal;
}
void wxXmlNode::AddChild(wxXmlNode *child)
{
if (m_children == NULL)
m_children = child;
else
{
wxXmlNode *ch = m_children;
while (ch->m_next) ch = ch->m_next;
ch->m_next = child;
}
child->m_next = NULL;
child->m_parent = this;
}
void wxXmlNode::InsertChild(wxXmlNode *child, wxXmlNode *before_node)
{
wxASSERT_MSG(before_node->GetParent() == this, wxT("wxXmlNode::InsertChild - the node has incorrect parent"));
if (m_children == before_node)
m_children = child;
else
{
wxXmlNode *ch = m_children;
while (ch->m_next != before_node) ch = ch->m_next;
ch->m_next = child;
}
child->m_parent = this;
child->m_next = before_node;
}
bool wxXmlNode::RemoveChild(wxXmlNode *child)
{
if (m_children == NULL)
return false;
else if (m_children == child)
{
m_children = child->m_next;
child->m_parent = NULL;
child->m_next = NULL;
return true;
}
else
{
wxXmlNode *ch = m_children;
while (ch->m_next)
{
if (ch->m_next == child)
{
ch->m_next = child->m_next;
child->m_parent = NULL;
child->m_next = NULL;
return true;
}
ch = ch->m_next;
}
return false;
}
}
void wxXmlNode::AddProperty(const wxString& name, const wxString& value)
{
AddProperty(new wxXmlProperty(name, value, NULL));
}
void wxXmlNode::AddProperty(wxXmlProperty *prop)
{
if (m_properties == NULL)
m_properties = prop;
else
{
wxXmlProperty *p = m_properties;
while (p->GetNext()) p = p->GetNext();
p->SetNext(prop);
}
}
bool wxXmlNode::DeleteProperty(const wxString& name)
{
wxXmlProperty *prop;
if (m_properties == NULL)
return false;
else if (m_properties->GetName() == name)
{
prop = m_properties;
m_properties = prop->GetNext();
prop->SetNext(NULL);
delete prop;
return true;
}
else
{
wxXmlProperty *p = m_properties;
while (p->GetNext())
{
if (p->GetNext()->GetName() == name)
{
prop = p->GetNext();
p->SetNext(prop->GetNext());
prop->SetNext(NULL);
delete prop;
return true;
}
p = p->GetNext();
}
return false;
}
}
//-----------------------------------------------------------------------------
// wxXmlDocument
//-----------------------------------------------------------------------------
wxXmlDocument::wxXmlDocument()
: m_version(wxT("1.0")), m_fileEncoding(wxT("utf-8")), m_root(NULL)
{
#if !wxUSE_UNICODE
m_encoding = wxT("UTF-8");
#endif
}
wxXmlDocument::wxXmlDocument(const wxString& filename, const wxString& encoding)
:wxObject(), m_root(NULL)
{
if ( !Load(filename, encoding) )
{
wxDELETE(m_root);
}
}
wxXmlDocument::wxXmlDocument(wxInputStream& stream, const wxString& encoding)
:wxObject(), m_root(NULL)
{
if ( !Load(stream, encoding) )
{
wxDELETE(m_root);
}
}
wxXmlDocument::wxXmlDocument(const wxXmlDocument& doc)
:wxObject()
{
DoCopy(doc);
}
wxXmlDocument& wxXmlDocument::operator=(const wxXmlDocument& doc)
{
wxDELETE(m_root);
DoCopy(doc);
return *this;
}
void wxXmlDocument::DoCopy(const wxXmlDocument& doc)
{
m_version = doc.m_version;
#if !wxUSE_UNICODE
m_encoding = doc.m_encoding;
#endif
m_fileEncoding = doc.m_fileEncoding;
m_root = new wxXmlNode(*doc.m_root);
}
bool wxXmlDocument::Load(const wxString& filename, const wxString& encoding)
{
wxFileInputStream stream(filename);
return Load(stream, encoding);
}
bool wxXmlDocument::Save(const wxString& filename) const
{
wxFileOutputStream stream(filename);
return Save(stream);
}
//-----------------------------------------------------------------------------
// wxXmlDocument loading routines
//-----------------------------------------------------------------------------
/*
FIXME:
- process all elements, including CDATA
*/
// converts Expat-produced string in UTF-8 into wxString.
inline static wxString CharToString(wxMBConv *conv,
const char *s, size_t len = wxSTRING_MAXLEN)
{
#if wxUSE_UNICODE
(void)conv;
return wxString(s, wxConvUTF8, len);
#else
if ( conv )
{
size_t nLen = (len != wxSTRING_MAXLEN) ? len :
wxConvUTF8.MB2WC((wchar_t*) NULL, s, 0);
wchar_t *buf = new wchar_t[nLen+1];
wxConvUTF8.MB2WC(buf, s, nLen);
buf[nLen] = 0;
wxString str(buf, *conv, len);
delete[] buf;
return str;
}
else
return wxString(s, len != wxSTRING_MAXLEN ? len : strlen(s));
#endif
}
struct wxXmlParsingContext
{
wxMBConv *conv;
wxXmlNode *root;
wxXmlNode *node;
wxXmlNode *lastAsText;
wxString encoding;
wxString version;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?