Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

xmlUtil::Substitute Class Reference

#include <Substitute.h>

List of all members.

Public Methods

 Substitute::Substitute (DOM_Document doc, std::string suffix=std::string("REF"))
int execute (DOM_Element treeTop)
 ~Substitute ()
 Destructor. More...


Private Methods

void sub (DOM_Element elt)

Private Attributes

DOM_Document m_doc
int m_count
std::string m_suffix
int m_suffixLen
int m_notFound


Detailed Description

The Substitute class will look up references to values (in attributes of type IDREF in a given subtree of a document) and replace the attribute with another that has as value the value of the reference. e.g., ... XREF="CsiLength" could get replaced by ... X = "33.12"

Definition at line 20 of file Substitute.h.


Constructor & Destructor Documentation

xmlUtil::Substitute::~Substitute   [inline]
 

Destructor.

Definition at line 44 of file Substitute.h.

00044 {};


Member Function Documentation

int xmlUtil::Substitute::execute DOM_Element    top
 

Do substitution for the subtree indicated, returning count. execute may be invoked repeatedly for different subtrees of the source document.

Parameters:
treeTop  the root of the subtree for which substitutions are to be performed.

Definition at line 20 of file Substitute.cxx.

References m_count, m_doc, and sub().

Referenced by main().

00020                                          {
00021     // Get rid of some inefficiency by means of the following imperfect
00022     // mechanism:
00023     //   An element may have an attribute called "substituted".  If it
00024     //   does, the attribute always has a default value of "false".
00025     //   The execute method looks for the attribute.  If it is there and
00026     //   has value "true", substitution has already been done, so just
00027     //   return.  If the attribute has value "false" or doesn't exist,
00028     //   go ahead and do the substitution.  Afterwards, if the attribute
00029     //   exists set its value to "true", but don't add any new attributes.
00030     //   Also as a matter of course always check the root element for
00031     //   a "substituted" attribute.
00032     //
00033     //   If an element and its descendent *both* have the substituted
00034     //   attribute, only the one passed to execute will have its substitute
00035     //   attribute examined and possibly changed.  This means it's possible
00036     //   for an element to have a "substituted" attribute value of "false"
00037     //   when it really should be "true", but never the other way around.
00038     //   
00039     DOM_Element docElt = m_doc.getDocumentElement();
00040     if ((docElt.getAttribute("substituted")).equals(DOMString("true"))) 
00041       return 0;
00042     
00043     if ((top.getAttribute("substituted")).equals(DOMString("true"))) return 0;
00044     DOM_Node curNode = top;
00045 
00046     // This is not explained anywhere in the xerces doc. that I
00047     // can see, but from the code in TreeWalkerImpl::acceptNode
00048     // this would seem to be the right value for whatToShow
00049     unsigned long whatToShow = 1 << (DOM_Node::ELEMENT_NODE -1);
00050 
00051     DOM_TreeWalker walker = m_doc.createTreeWalker(top, whatToShow, 0, 0);
00052     m_count = 0;
00053     while (curNode != DOM_Node() ) {
00054       sub(static_cast<DOM_Element &> (curNode));
00055       curNode = walker.nextNode();
00056     }
00057     DOM_Attr subNode = top.getAttributeNode("substituted");
00058     if (subNode != DOM_Attr()) { 
00059       subNode.setValue("true");
00060     }
00061 
00062     return m_count;
00063   }

void xmlUtil::Substitute::sub DOM_Element    elt [private]
 

Handle a single element (invoked from public execute method)

Definition at line 65 of file Substitute.cxx.

References m_count, m_doc, m_notFound, m_suffix, and m_suffixLen.

Referenced by execute().

00065                                       {
00066     DOM_NamedNodeMap attMap = elt.getAttributes();
00067     int   nAtt = attMap.getLength();
00068     int   iAtt;
00069     std::vector<DOMString> toProcess;
00070     std::vector<unsigned> toProcessPos;
00071     //    std::vector<DOM_Node> toDelete;
00072 
00073     for (iAtt = 0; iAtt <nAtt; iAtt++) {
00074       DOM_Node att = attMap.item(iAtt);
00075       //      if (att != DOM_Node()) { // probably not necessary
00076       DOMString  attString = att.getNodeName();
00077       std::string attName = std::string(xml::Dom::transToChar(attString));
00078       
00079         // Look for suffix
00080       unsigned pos = attName.find(m_suffix, attName.size() - m_suffixLen);
00081       if  (pos < attName.size())  { // found
00082         toProcess.push_back(attString);
00083         toProcessPos.push_back(pos);
00084       }
00085     }
00086 
00087     // Now process by name
00088     while (toProcess.size() > 0) {
00089       DOMString oldAttString = toProcess.back();
00090       std::string oldAttName = 
00091         std::string(xml::Dom::transToChar(oldAttString));
00092       unsigned  pos = toProcessPos.back();
00093       toProcess.pop_back();
00094       toProcessPos.pop_back();
00095       DOM_Element constElt =
00096         m_doc.getElementById(elt.getAttribute(oldAttString));
00097       if (constElt == DOM_Element() ) { // shouldn't happen
00098         m_notFound++;
00099         continue;
00100       }
00101       // Build the new attribute
00102       DOMString val = constElt.getAttribute(DOMString("value"));
00103 
00104       // If the element referred to is a <prim>, we should be done
00105       // because it always has a value.  If it's a <const>
00106       // we may have to evaluate it.
00107       if (val == DOMString()) { // try evaluating it
00108         Arith curArith(constElt);
00109         double evalValue = curArith.evaluate();
00110         curArith.saveValue();
00111         val = constElt.getAttribute(DOMString("value"));
00112       }
00113 
00114       std::string newAttName = oldAttName.erase(pos, oldAttName.size()  );
00115       elt.setAttribute(DOMString(newAttName.c_str()), val);
00116       elt.removeAttribute(oldAttString);
00117       m_count++;
00118     }
00119 
00120     // Now delete each saved attribute node 
00121     // while (toDelete.size() > 0) {
00122     //      DOM_Node att = toDelete.back();
00123     //      toDelete.pop_back();
00124     //      elt.removeAttributeNode(static_cast <DOM_Attr &>(att));
00125     //    }
00126   }

xmlUtil::Substitute::Substitute::Substitute DOM_Document    doc,
std::string    suffix = std::string("REF")
 

A Substitute object is configured by specifying the document in which substitutions are to occur and the suffix which will be used to find attributes for which substitutions are requested.

Parameters:
doc  The document for which substitutions are to be performed
suffix  The suffix which identitifies references in the source docoument (defaults to "REF")


Member Data Documentation

int xmlUtil::Substitute::m_count [private]
 

Keep track of #subs done for one execute

Definition at line 48 of file Substitute.h.

Referenced by execute(), and sub().

DOM_Document xmlUtil::Substitute::m_doc [private]
 

Document on which substitutions may be done

Definition at line 47 of file Substitute.h.

Referenced by execute(), and sub().

int xmlUtil::Substitute::m_notFound [private]
 

count of id's not found-- shouldn't happen

Definition at line 51 of file Substitute.h.

Referenced by sub().

std::string xmlUtil::Substitute::m_suffix [private]
 

Suffix identifying references

Definition at line 49 of file Substitute.h.

Referenced by sub().

int xmlUtil::Substitute::m_suffixLen [private]
 

Definition at line 50 of file Substitute.h.

Referenced by sub().


The documentation for this class was generated from the following files:
Generated on Wed Oct 16 14:02:50 2002 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001