//====================================================================== //====================================================================== bool XMLDocument::doAttributesMatch(DOM_Node currNode, DataTypeAttribute** dtAttributes) { DOM_NamedNodeMap nnodeMap = currNode.getAttributes(); int len = nnodeMap.getLength(); int a = 0; DataTypeAttribute* dtAttribute; while ((dtAttribute = (DataTypeAttribute*)dtAttributes[a++]) != (DataTypeAttribute*)NULL) { bool isFound = false; for (int i = 0; i < len && !isFound; i++) { DOM_Node attNode = nnodeMap.item(i); char* tmp = attNode.getNodeName().transcode(); char* tmp1 = attNode.getNodeValue().transcode(); if (strcmp(dtAttribute->getName(), tmp) == 0 && strcmp(dtAttribute->getValue(), tmp1) == 0) { isFound = true; } delete[] tmp; delete[] tmp1; } if (!isFound) return false; } return true; }
//====================================================================== //====================================================================== bool XMLDocument::setValue(DOM_Node currNode, char* path, DataTypeAttribute** dtAttributes, char* value) { if (mDoc == NULL) return false; if (path == NULL) return false; DOM_Node child = getNode(currNode, path, dtAttributes); if (child == NULL) return false; DOM_Node parent = child.getParentNode(); if (parent == NULL) return false; DOM_Node grandChild = child.getFirstChild(); short nType = DOM_Node::TEXT_NODE; if (grandChild != NULL) { nType = grandChild.getNodeType(); if (nType != DOM_Node::TEXT_NODE && nType != DOM_Node::CDATA_SECTION_NODE) return false; } char* childName = child.getNodeName().transcode(); DOM_NamedNodeMap nnodeMap = child.getAttributes(); parent.removeChild(child); DOM_Element childElement = mDoc.createElement(childName); delete[] childName; for (unsigned int i = 0; i < nnodeMap.getLength(); i++) { DOM_Node attNode = nnodeMap.item(i); childElement.setAttribute(attNode.getNodeName(), attNode.getNodeValue()); } if (nType == DOM_Node::TEXT_NODE) { DOM_Text childText = mDoc.createTextNode((value == NULL)?"":value); childElement.appendChild(childText); } else { DOM_CDATASection childCData = mDoc.createCDATASection((value == NULL)?"":value); childElement.appendChild(childCData); } parent.appendChild(childElement); return true; }
DOM_Node XMLDocument::clone(DOM_Node currNode) { switch (currNode.getNodeType()) { case DOM_Node::ELEMENT_NODE: { DOM_Element elem = mDoc.createElement(currNode.getNodeName()); DOM_NamedNodeMap nnodeMap = currNode.getAttributes(); for (unsigned int i = 0; i < nnodeMap.getLength(); i++) { DOM_Node attNode = nnodeMap.item(i); elem.setAttribute(attNode.getNodeName(), attNode.getNodeValue()); } DOM_Node child = currNode.getFirstChild(); while (child != NULL) { DOM_Node cNode = clone(child); if (cNode != NULL) elem.appendChild(cNode); child = child.getNextSibling(); } return (DOM_Node)elem; } case DOM_Node::TEXT_NODE: { DOM_Text childText = mDoc.createTextNode(currNode.getNodeValue()); return (DOM_Node)childText; } case DOM_Node::CDATA_SECTION_NODE: { DOM_CDATASection childCData = mDoc.createCDATASection(currNode.getNodeValue()); return (DOM_Node)childCData; } default: { return NULL_DOM_Node; } } }
// --------------------------------------------------------------------------- // ostream << DOM_Node // // Stream out a DOM node, and, recursively, all of its children. This // function is the heart of writing a DOM tree out as XML source. Give it // a document node and it will do the whole thing. // --------------------------------------------------------------------------- ostream& operator<<(ostream& target, DOM_Node& toWrite) { // Get the name and value out for convenience DOMString nodeName = toWrite.getNodeName(); DOMString nodeValue = toWrite.getNodeValue(); unsigned long lent = nodeValue.length(); switch (toWrite.getNodeType()) { case DOM_Node::TEXT_NODE: { gFormatter->formatBuf(nodeValue.rawBuffer(), lent, XMLFormatter::CharEscapes); break; } case DOM_Node::PROCESSING_INSTRUCTION_NODE : { *gFormatter << XMLFormatter::NoEscapes << gStartPI << nodeName; if (lent > 0) { *gFormatter << chSpace << nodeValue; } *gFormatter << XMLFormatter::NoEscapes << gEndPI; break; } case DOM_Node::DOCUMENT_NODE : { DOM_Node child = toWrite.getFirstChild(); while( child != 0) { target << child; // add linefeed in requested output encoding *gFormatter << chLF; target << flush; child = child.getNextSibling(); } break; } case DOM_Node::ELEMENT_NODE : { // The name has to be representable without any escapes *gFormatter << XMLFormatter::NoEscapes << chOpenAngle << nodeName; // Output the element start tag. // Output any attributes on this element DOM_NamedNodeMap attributes = toWrite.getAttributes(); int attrCount = attributes.getLength(); for (int i = 0; i < attrCount; i++) { DOM_Node attribute = attributes.item(i); // // Again the name has to be completely representable. But the // attribute can have refs and requires the attribute style // escaping. // *gFormatter << XMLFormatter::NoEscapes << chSpace << attribute.getNodeName() << chEqual << chDoubleQuote << XMLFormatter::AttrEscapes << attribute.getNodeValue() << XMLFormatter::NoEscapes << chDoubleQuote; } // // Test for the presence of children, which includes both // text content and nested elements. // DOM_Node child = toWrite.getFirstChild(); if (child != 0) { // There are children. Close start-tag, and output children. // No escapes are legal here *gFormatter << XMLFormatter::NoEscapes << chCloseAngle; while( child != 0) { target << child; child = child.getNextSibling(); } // // Done with children. Output the end tag. // *gFormatter << XMLFormatter::NoEscapes << gEndElement << nodeName << chCloseAngle; } else { // // There were no children. Output the short form close of // the element start tag, making it an empty-element tag. // *gFormatter << XMLFormatter::NoEscapes << chForwardSlash << chCloseAngle; } break; } case DOM_Node::ENTITY_REFERENCE_NODE: { DOM_Node child; #if 0 for (child = toWrite.getFirstChild(); child != 0; child = child.getNextSibling()) { target << child; } #else // // Instead of printing the refernece tree // we'd output the actual text as it appeared in the xml file. // This would be the case when -e option was chosen // *gFormatter << XMLFormatter::NoEscapes << chAmpersand << nodeName << chSemiColon; #endif break; } case DOM_Node::CDATA_SECTION_NODE: { *gFormatter << XMLFormatter::NoEscapes << gStartCDATA << nodeValue << gEndCDATA; break; } case DOM_Node::COMMENT_NODE: { *gFormatter << XMLFormatter::NoEscapes << gStartComment << nodeValue << gEndComment; break; } case DOM_Node::DOCUMENT_TYPE_NODE: { DOM_DocumentType doctype = (DOM_DocumentType &)toWrite;; *gFormatter << XMLFormatter::NoEscapes << gStartDoctype << nodeName; DOMString id = doctype.getPublicId(); if (id != 0) { *gFormatter << XMLFormatter::NoEscapes << chSpace << gPublic << id << chDoubleQuote; id = doctype.getSystemId(); if (id != 0) { *gFormatter << XMLFormatter::NoEscapes << chSpace << chDoubleQuote << id << chDoubleQuote; } } else { id = doctype.getSystemId(); if (id != 0) { *gFormatter << XMLFormatter::NoEscapes << chSpace << gSystem << id << chDoubleQuote; } } id = doctype.getInternalSubset(); if (id !=0) *gFormatter << XMLFormatter::NoEscapes << chOpenSquare << id << chCloseSquare; *gFormatter << XMLFormatter::NoEscapes << chCloseAngle; break; } case DOM_Node::ENTITY_NODE: { *gFormatter << XMLFormatter::NoEscapes << gStartEntity << nodeName; DOMString id = ((DOM_Entity &)toWrite).getPublicId(); if (id != 0) *gFormatter << XMLFormatter::NoEscapes << gPublic << id << chDoubleQuote; id = ((DOM_Entity &)toWrite).getSystemId(); if (id != 0) *gFormatter << XMLFormatter::NoEscapes << gSystem << id << chDoubleQuote; id = ((DOM_Entity &)toWrite).getNotationName(); if (id != 0) *gFormatter << XMLFormatter::NoEscapes << gNotation << id << chDoubleQuote; *gFormatter << XMLFormatter::NoEscapes << chCloseAngle << chLF; break; } case DOM_Node::XML_DECL_NODE: { DOMString str; *gFormatter << gXMLDecl1 << ((DOM_XMLDecl &)toWrite).getVersion(); *gFormatter << gXMLDecl2 << gEncodingName; str = ((DOM_XMLDecl &)toWrite).getStandalone(); if (str != 0) *gFormatter << gXMLDecl3 << str; *gFormatter << gXMLDecl4; break; } default: cerr << "Unrecognized node type = " << (long)toWrite.getNodeType() << endl; } return target; }
char* XMLDocument::encode(DOM_Node currNode) { string result = ""; if (currNode == NULL) return strclone((char*)result.c_str()); switch (currNode.getNodeType()) { case DOM_Node::ELEMENT_NODE: { char* tmp = currNode.getNodeName().transcode(); result += (string)"<" + (string)tmp; delete[] tmp; DOM_NamedNodeMap nnodeMap = currNode.getAttributes(); for (unsigned int i = 0; i < nnodeMap.getLength(); i++) { DOM_Node attNode = nnodeMap.item(i); tmp = attNode.getNodeName().transcode(); char* tmp1 = attNode.getNodeValue().transcode(); result += (string)" " + (string)tmp + (string)"=\"" + (string)tmp1 + (string)"\""; delete[] tmp; delete[] tmp1; } result += (string)">"; DOM_Node child = currNode.getFirstChild(); while (child != NULL) { char *childStr = encode(child); result += childStr; delete[] childStr; child = child.getNextSibling(); } tmp = currNode.getNodeName().transcode(); result += (string)"</" + (string)tmp + ">"; delete[] tmp; return strclone((char*)result.c_str()); } case DOM_Node::TEXT_NODE: case DOM_Node::CDATA_SECTION_NODE: { static char reservedChars[] = "<>&'\""; char *str = currNode.getNodeValue().transcode(); bool bSpecialChars = false; int len = strlen(str); for (int i = 0; i < len; i++) { if (strchr(reservedChars, str[i]) != NULL) { bSpecialChars = true; break; } } if (bSpecialChars == false) result += (string)str; else result += (string)"<![CDATA[" + (string)str + (string)"]]>"; delete[] str; return strclone((char*)result.c_str()); } default: { return strclone((char*)result.c_str()); } } }