/*******************************************************************/
/* XDMF */
/* eXtensible Data Model and Format */
/* */
/* Id : Id */
/* Date : $Date$ */
/* Version : $Revision$ */
/* */
/* Author: */
/* Jerry A. Clarke */
/* clarke@arl.army.mil */
/* US Army Research Laboratory */
/* Aberdeen Proving Ground, MD */
/* */
/* Copyright @ 2002 US Army Research Laboratory */
/* All Rights Reserved */
/* See Copyright.txt or http://www.arl.hpc.mil/ice for details */
/* */
/* This software is distributed WITHOUT ANY WARRANTY; without */
/* even the implied warranty of MERCHANTABILITY or FITNESS */
/* FOR A PARTICULAR PURPOSE. See the above copyright notice */
/* for more information. */
/* */
/*******************************************************************/
#ifndef __XdmfDOM_h
#define __XdmfDOM_h
#include "XdmfLightData.h"
namespace xdmf2
{
//! Class for XML Parsing using the Document Object Model
/*!
This is the Base XML Parsing Object. A XdmfDOM will
read the XML and build an internal tree structure. The
tree can then be walked and queried. Any node can be
"serialized". This generates an XML string that implements
the node and all of its' children.
Many other Xdmf Classes (XdmfGrid, XdmfTopology, etc.) use this
class to parse and generate XML. The DOM can accept XML from a
String or from a File. Once \b PARSED the resulting tree can be
modified by adding or deleting nodes and then "serialized" to produce
XML. For example, the following XML might be in MyFile.xml :
\verbatim
Text for Second Child
\endverbatim
The DOM might manipulate the XML with :
\code
XdmfDOM *DOM = new XdmfDOM();
XdmfXmlNode *Parent, *FirstChild, *SecondChild;
// Parse the XML File
DOM->SetInputFileName("MyFile.xml");
DOM->Parse();
// Find the first element with TAG = Tag1
Parent = DOM->FindElement("Tag1");
// Find the first (zero based) Tag2 below Parent
FirstChild = DOM->FindElement("Tag2", 0, Parent);
cout << "The Name of the First Child is <" << DOM->Get(FirstChild, "Name") << ">" << endl;
// Find the second (zero based) Tag2 below Parent
SecondChild = DOM->FindElement("Tag2", 1, Parent);
DOM->Set(SecondChild, "Age", "10");
DOM->DeleteNode(FirstChild);
cout << endl << "XML = " << endl << DOM->Serialize(Parent) << endl;
\endcode
Would Procude the following Output:
\verbatim
The Name of the First Child is
XML =
Text for Second Child
\endverbatim
*/
class XDMF_EXPORT XdmfDOM : public XdmfLightData {
public :
XdmfDOM();
~XdmfDOM();
XdmfConstString GetClassName() { return("XdmfDOM"); } ;
//! Set the FileName of the XML Description : stdin or Filename
XdmfInt32 SetInputFileName( XdmfConstString Filename );
//! Set the FileName of the XML Description : stderr or Filename
XdmfInt32 SetOutputFileName( XdmfConstString Filename );
//! Get the FileName of the XML Description
XdmfConstString GetInputFileName() { return(this->GetFileName()); };
//! Get the FileName of the XML Description
XdmfGetStringMacro( OutputFileName );
/*! Set Parser Options. See libxml documentation for values
Default = XML_PARSE_NONET | XML_PARSE_XINCLUDE
*/
XdmfSetValueMacro(ParserOptions, XdmfInt32);
//! Get the XML destination
XdmfGetValueMacro( Output, ostream *);
//! Set the XML destination
XdmfSetValueMacro( Output, ostream *);
//! Get the XML destination
XdmfGetValueMacro( Input, istream *);
//! Set the XML destination
XdmfSetValueMacro( Input, istream *);
//! Generate a Standard XDMF Header
XdmfInt32 GenerateHead( void );
//! Check status of Xdmf.dtd inclusion in the XML header
XdmfGetValueMacro( DTD, XdmfInt32 );
//! Set the status of the Xdmf.dtd inclusion in the XML header
XdmfSetValueMacro( DTD, XdmfInt32 );
//! Output a String to the XML document
XdmfInt32 Puts( XdmfConstString String );
//! Generate a Standard XDMF Tail
XdmfInt32 GenerateTail( void );
//! Return the Low Level root of the tree
XdmfXmlNode GetTree( void ) {return(this->Tree);} ;
//! Parse XML without re-initializing entire DOM
XdmfXmlNode __Parse(XdmfConstString xml, XdmfXmlDoc *Doc=NULL);
//! Re-Initialize and Parse
XdmfInt32 Parse(XdmfConstString xml = NULL );
//! Get the Root Node
XdmfXmlNode GetRoot( void );
//! Get the Number of immediate Children
XdmfInt64 GetNumberOfChildren( XdmfXmlNode node = NULL);
//! Get The N'th Child
XdmfXmlNode GetChild( XdmfInt64 Index , XdmfXmlNode Node );
//! Get Number of Attribute in a Node
XdmfInt32 GetNumberOfAttributes( XdmfXmlNode Node );
//! Get Attribute Name by Index
XdmfConstString GetAttributeName( XdmfXmlNode Node, XdmfInt32 Index );
//! Is the XdmfXmlNode a child of "Start" in this DOM
XdmfInt32 IsChild( XdmfXmlNode ChildToCheck, XdmfXmlNode Node = NULL );
//! Convert DOM to XML String
XdmfConstString Serialize(XdmfXmlNode node = NULL);
/*! Dump the XML contents
\param Output FileName of Output. Default is to use current OutputFileName
*/
XdmfInt32 Write(XdmfConstString Output = NULL);
//! Insert a node into a DOM
XdmfXmlNode Insert(XdmfXmlNode parent, XdmfXmlNode node);
//! Create a node from an XML string and insert it in the DOM
XdmfXmlNode InsertFromString(XdmfXmlNode parent, XdmfConstString xml );
//! Create a new document
XdmfXmlNode Create(XdmfConstString RootElementName="Xdmf", XdmfConstString Version="2.0");
//! Create a new node under an existing one
XdmfXmlNode InsertNew(XdmfXmlNode Parent, XdmfConstString Type);
//! Delete a node
XdmfInt32 DeleteNode(XdmfXmlNode node);
//! Find the n'th occurance of a certain node type
/*!
Walk the tree and find the first
element that is of a certain type.
Index ( 0 based ) can be used to find the n'th
node that satisfies the criteria. The search can also
tree starting at a particular node. IgnoreInfo allows
the "Information" Elements not to be counted against Index.
*/
XdmfXmlNode FindElement(XdmfConstString TagName,
XdmfInt32 Index= 0,
XdmfXmlNode Node = NULL,
XdmfInt32 IgnoreInfo=1);
/*!
Find the next sibling for the node that is of a certain type. IgnoreInfo allows
the "Information" elements to be skipped.
*/
XdmfXmlNode FindNextElement(XdmfConstString TagName,
XdmfXmlNode Node,
XdmfInt32 IgnoreInfo=1);
/*! Find DataItem, DataStructure, or DataTransform
This is needed for backward compatibility but will
be removed in the future and XML will be forced
to use
file.h5
\endverbatim
\code
Dom->Get(Node, "Name") // will return "Test"
Dom->Get(Node, "Type") // will return "Data"
Dom->Get(Node, "Other") // will return NULL ; there is none
Dom->Get(Node, "CData") // will return "file.h5" ; the Character Data
\endcode
*/
XdmfConstString Get(XdmfXmlNode Node, XdmfConstString Attribute);
//! Get an Attribute. Does not check for CDATA so it's faster
XdmfConstString GetAttribute(XdmfXmlNode Node, XdmfConstString Attribute);
//! Get the CDATA of a Node
XdmfConstString GetCData(XdmfXmlNode Node);
//! Set a new Attribute=Value in a Node
void Set( XdmfXmlNode Node, XdmfConstString Attribute, XdmfConstString Value );
protected :
XdmfString NdgmHost;
XdmfString OutputFileName;
ostream *Output;
istream *Input;
XdmfXmlDoc Doc;
XdmfXmlNode Tree;
XdmfInt32 ParserOptions;
XdmfInt32 DTD;
void FreePrivateData(XdmfXmlNode node);
void FreeDoc(XdmfXmlDoc doc);
};
extern XDMF_EXPORT XdmfDOM *HandleToXdmfDOM( XdmfConstString Source );
}
#endif