#include <Substitute.h>
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 |
Definition at line 20 of file Substitute.h.
|
|
Destructor.
Definition at line 44 of file Substitute.h.
00044 {};
|
|
|
Do substitution for the subtree indicated, returning count. execute may be invoked repeatedly for different subtrees of the source document.
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 }
|
|
|
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 }
|
|
||||||||||||
|
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.
|
|
|
Keep track of #subs done for one execute Definition at line 48 of file Substitute.h. |
|
|
Document on which substitutions may be done Definition at line 47 of file Substitute.h. |
|
|
count of id's not found-- shouldn't happen Definition at line 51 of file Substitute.h. Referenced by sub(). |
|
|
Suffix identifying references Definition at line 49 of file Substitute.h. Referenced by sub(). |
|
|
Definition at line 50 of file Substitute.h. Referenced by sub(). |
1.2.13.1 written by Dimitri van Heesch,
© 1997-2001