Normalizer.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:18k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2003 The Apache Software Foundation->  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution->
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission-> For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation->
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 2001, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. #include "Normalizer.hpp"
  57. #include <xercesc/util/PlatformUtils.hpp>
  58. #include <xercesc/framework/StdOutFormatTarget.hpp>
  59. #include <xercesc/framework/XMLBuffer.hpp>
  60. #include <xercesc/parsers/XercesDOMParser.hpp>
  61. #include <iostream.h>
  62. #include <xercesc/util/XMLUni.hpp>
  63. #include <xercesc/util/XMLUniDefs.hpp>
  64. #include "../../../src/xercesc/dom/impl/DOMConfigurationImpl.hpp"
  65. #include "../../../src/xercesc/dom/impl/DOMDocumentImpl.hpp"
  66. #include "../../../src/xercesc/dom/impl/DOMEntityImpl.hpp"
  67. #include "../../../src/xercesc/dom/impl/DOMEntityReferenceImpl.hpp"
  68. // ---------------------------------------------------------------------------
  69. //  This is a simple class that lets us do easy (though not terribly efficient)
  70. //  trancoding of char* data to XMLCh data.
  71. // ---------------------------------------------------------------------------
  72. class XStr
  73. {
  74. public :
  75.     // -----------------------------------------------------------------------
  76.     //  Constructors and Destructor
  77.     // -----------------------------------------------------------------------
  78.     XStr(const char* const toTranscode)
  79.     {
  80.         // Call the private transcoding method
  81.         fUnicodeForm = XMLString::transcode(toTranscode);
  82.     }
  83.     ~XStr()
  84.     {
  85.         XMLString::release(&fUnicodeForm);
  86.     }
  87.     // -----------------------------------------------------------------------
  88.     //  Getter methods
  89.     // -----------------------------------------------------------------------
  90.     const XMLCh* unicodeForm() const
  91.     {
  92.         return fUnicodeForm;
  93.     }
  94. private :
  95.     // -----------------------------------------------------------------------
  96.     //  Private data members
  97.     //
  98.     //  fUnicodeForm
  99.     //      This is the Unicode XMLCh format of the string.
  100.     // -----------------------------------------------------------------------
  101.     XMLCh*   fUnicodeForm;
  102. };
  103. #define X(str) XStr(str).unicodeForm()
  104. //  This is a simple class that lets us do easy (though not terribly efficient)
  105. //  trancoding of XMLCh data to local code page for display.
  106. // ---------------------------------------------------------------------------
  107. class StrX
  108. {
  109. public :
  110.     // -----------------------------------------------------------------------
  111.     //  Constructors and Destructor
  112.     // -----------------------------------------------------------------------
  113.     StrX(const XMLCh* const toTranscode)
  114.     {
  115.         // Call the private transcoding method
  116.         fLocalForm = XMLString::transcode(toTranscode);
  117.     }
  118.     ~StrX()
  119.     {
  120.         XMLString::release(&fLocalForm);
  121.     }
  122.     // -----------------------------------------------------------------------
  123.     //  Getter methods
  124.     // -----------------------------------------------------------------------
  125.     const char* localForm() const
  126.     {
  127.         return fLocalForm;
  128.     }
  129. private :
  130.     // -----------------------------------------------------------------------
  131.     //  Private data members
  132.     //
  133.     //  fLocalForm
  134.     //      This is the local code page form of the string.
  135.     // -----------------------------------------------------------------------
  136.     char*   fLocalForm;
  137. };
  138. #define StrX(str) StrX(str).localForm()
  139. Normalizer::Normalizer() {
  140.     try
  141.     {
  142.         XMLPlatformUtils::Initialize();
  143.     }
  144.     catch(const XMLException &toCatch)
  145.     {
  146.         cerr << "Error during Xerces-c Initialization.n"
  147.              << "  Exception message:"
  148.              << StrX(toCatch.getMessage()) << endl;
  149.     }
  150.     parser = 0;
  151. }
  152. Normalizer::~Normalizer() {
  153.     XMLPlatformUtils::Terminate();
  154. }
  155. void Normalizer::printEntityRefNodes(DOMElement *ele) {
  156.     
  157.     DOMNode *child = ele->getFirstChild();
  158.     while(child != 0) {
  159.         if(child->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
  160.             cout << "start of entity ref node" << endl;
  161.             DOMNode *entChild = ((DOMEntityReference*)child)->getFirstChild();
  162.             while(entChild != 0) {
  163.                 serializeNode(entChild);
  164.                 entChild = entChild->getNextSibling();
  165.             }
  166.             cout << "nend of entity ref nodenn" << endl;
  167.         }
  168.         if(child->getNodeType() == DOMNode::ELEMENT_NODE) {
  169.             printEntityRefNodes((DOMElement*)child);
  170.         }
  171.         child = child->getNextSibling();
  172.     }
  173.     
  174. }
  175. bool Normalizer::handleError(const DOMError& domError)
  176. {
  177.     // Display whatever error message passed from the serializer
  178.     if (domError.getSeverity() == DOMError::DOM_SEVERITY_WARNING)
  179.         cerr << "nWarning Message: ";
  180.     else if (domError.getSeverity() == DOMError::DOM_SEVERITY_ERROR)
  181.         cerr << "nError Message: ";
  182.     else
  183.         cerr << "nFatal Message: ";
  184.     char *msg = XMLString::transcode(domError.getMessage());
  185.     cerr<< msg <<endl;
  186.     XMLString::release(&msg);
  187.     cerr << "Related data ";
  188.     msg = XMLString::transcode(((DOMNode*)domError.getRelatedData())->getNodeName());
  189.     cerr<< msg <<endl;
  190.     XMLString::release(&msg);
  191.  
  192.     // continue serialization if possible.
  193.     return true;
  194. }
  195. DOMDocument* Normalizer::createDocument() {
  196.     XMLCh coreStr[100];
  197.     XMLString::transcode("Core",coreStr,99);
  198.     DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(coreStr);
  199.     return impl->createDocument();
  200. };
  201. void Normalizer::serializeNode(const DOMNode * const node) {
  202.     XMLCh tempStr[100];
  203.     XMLString::transcode("LS", tempStr, 99);
  204.     DOMImplementation *impl          = DOMImplementationRegistry::getDOMImplementation(tempStr);
  205.     DOMWriter         *theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter();
  206.     theSerializer->setFeature(X("format-pretty-print"), true);
  207.     XMLFormatTarget *myFormTarget;
  208.     myFormTarget = new StdOutFormatTarget();
  209.     theSerializer->writeNode(myFormTarget, *node);
  210. }
  211. int main(int argc, char **argv) {
  212.     Normalizer *normalizer = new Normalizer();
  213.     DOMDocument *doc = normalizer->createDocument();
  214.     bool *tmpTrue = new bool(true);
  215.     bool *tmpFalse = new bool(false);
  216.     DOMElement* docFirstElement = doc->createElementNS(X("http://www.test.com"),X("docEle"));
  217.     doc->appendChild(docFirstElement);
  218.     DOMElement* docFirstElementChild = doc->createElementNS(X("http://www.test2.com"),X("docEleChild"));
  219.     docFirstElement->appendChild(docFirstElementChild);
  220.     //create default ns
  221.     doc->normalizeDocument();
  222.     normalizer->serializeNode(doc);
  223.     cout << "nn";
  224.     //add in binding
  225.     docFirstElement->setPrefix(X("po"));
  226.     doc->normalizeDocument();
  227.     normalizer->serializeNode(doc);
  228.     cout << "nn";
  229.     //use default
  230.     DOMElement* docFirstElementChildChild = doc->createElementNS(X("http://www.test2.com"),X("docEleChildChild"));
  231.     docFirstElementChild->appendChild(docFirstElementChildChild);
  232.     doc->normalizeDocument();
  233.     normalizer->serializeNode(doc);
  234.     cout << "nn";
  235.     //use a binding
  236.     XMLBuffer buf;
  237.     buf.set(XMLUni::fgXMLNSString);
  238.     buf.append(chColon);
  239.     buf.append(X("po2"));
  240.     docFirstElementChild->removeAttributeNS(XMLUni::fgXMLNSURIName, XMLUni::fgXMLNSString);
  241.     docFirstElement->removeAttributeNS(XMLUni::fgXMLNSURIName, XMLUni::fgXMLNSString);
  242.     docFirstElement->setAttributeNS(XMLUni::fgXMLNSURIName, buf.getRawBuffer(), X("http://www.test2.com"));
  243.     docFirstElementChild->setPrefix(X("po2"));
  244.     doc->normalizeDocument();
  245.     normalizer->serializeNode(doc);
  246.     cout << "nn";
  247.     //some siblngs to ensure the scope stacks are working
  248.     docFirstElementChildChild = doc->createElementNS(X("http://www.test3.com"),X("docEleChildChild2"));
  249.     docFirstElementChild->appendChild(docFirstElementChildChild);
  250.     docFirstElementChildChild = doc->createElementNS(X("http://www.test4.com"),X("po4:docEleChildChild3"));
  251.     docFirstElementChild->appendChild(docFirstElementChildChild);
  252.     docFirstElementChildChild = doc->createElementNS(X("http://www.test4.com"),X("po4:docEleChildChild4"));
  253.     docFirstElementChild->appendChild(docFirstElementChildChild);
  254.     doc->normalizeDocument();
  255.     normalizer->serializeNode(doc);
  256.     cout << "nn";
  257.     //conflicting prefix
  258.     docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("po4"), X("conflict"));
  259.     doc->normalizeDocument();
  260.     normalizer->serializeNode(doc);
  261.     cout << "nn";
  262.     
  263.     //conflicting default
  264.     docFirstElementChildChild = doc->createElementNS(X("http://www.test4.com"),X("docEleChildChild5"));
  265.     docFirstElementChild->appendChild(docFirstElementChildChild);
  266.     docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, XMLUni::fgXMLNSString, X("conflict"));
  267.     doc->normalizeDocument();
  268.     normalizer->serializeNode(doc);
  269.     cout << "nn";
  270.     //set the xmlns to ""
  271.     DOMElement *noNamespaceEle = doc->createElementNS(X(""),X("noNamespace"));
  272.     docFirstElementChildChild->appendChild(noNamespaceEle);
  273.     doc->normalizeDocument();
  274.     normalizer->serializeNode(doc);
  275.     cout << "nn";
  276.     //now lets do a bit off attribute testing on the doc ele
  277.     docFirstElement->setAttributeNS(X("http://testattr.com"), X("attr1"), X("value"));
  278.     docFirstElement->setAttributeNS(X("http://testattr.com"), X("attr2"), X("value"));
  279.     docFirstElement->setAttributeNS(X("http://testattr2.com"), X("attr3"), X("value"));
  280.     docFirstElement->setAttributeNS(X("http://www.test.com"), X("attr4"), X("value"));
  281.     docFirstElement->setAttributeNS(X("http://testattr2.com"), X("po:attr5"), X("value"));
  282.     docFirstElement->setAttributeNS(X("http://testattr2.com"), X("poFake:attr6"), X("value"));
  283.     docFirstElement->setAttributeNS(X("http://testattr3.com"), X("po3:attr7"), X("value"));
  284.     doc->normalizeDocument();
  285.     normalizer->serializeNode(doc);
  286.     cout << "nn";
  287.     //and now on one of its children
  288.     docFirstElementChildChild->setAttributeNS(X("http://testattr.com"), X("attr1"), X("value"));
  289.     docFirstElementChildChild->setAttributeNS(X("http://testattr.com"), X("attr2"), X("value"));
  290.     docFirstElementChildChild->setAttributeNS(X("http://testattr2.com"), X("attr3"), X("value"));
  291.     docFirstElementChildChild->setAttributeNS(X("http://www.test.com"), X("attr4"), X("value"));
  292.     docFirstElementChildChild->setAttributeNS(X("http://testattr2.com"), X("po:attr5"), X("value"));
  293.     docFirstElementChildChild->setAttributeNS(X("http://testattr2.com"), X("poFake:attr6"), X("value"));
  294.     docFirstElementChildChild->setAttributeNS(X("http://testattr3.com"), X("po3:attr7"), X("value"));
  295.     docFirstElementChildChild->setAttributeNS(X("http://testattr4.com"), X("po4:attr8"), X("value"));
  296.     
  297.     //test for a clash with our NSx attrs
  298.     docFirstElementChildChild->setAttributeNS(X("http://testclash.com"), X("NS1:attr9"), X("value"));
  299.     docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:NS1"), X("http://testclash.com"));
  300.     //clash with standard prefix
  301.     docFirstElementChildChild->setAttributeNS(X("http://testattr5.com"), X("po:attr10"), X("value"));
  302.     doc->normalizeDocument();
  303.     normalizer->serializeNode(doc);
  304.     cout << "nn";
  305.     //2 prefix with the same uri
  306.     docFirstElementChildChild = doc->createElementNS(X("http://www.uri1.com"),X("docEleChildChild6"));
  307.     docFirstElementChild->appendChild(docFirstElementChildChild);
  308.     docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:uri1"), X("http://www.uri1.com"));
  309.     docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:uri1b"), X("http://www.uri1.com"));
  310.     docFirstElementChildChild->setAttributeNS(X("http://www.uri1.com"), X("uri1:attr1"), X("value"));
  311.     docFirstElementChildChild->setAttributeNS(X("http://www.uri1.com"), X("uri1b:attr2"), X("value"));
  312.     doc->normalizeDocument();
  313.     normalizer->serializeNode(doc);
  314.     cout << "nn";
  315.     //check to see we use the nearest binding and for more inheritence
  316.     DOMElement *docFirstElementChildChildChild = doc->createElementNS(X("http://www.uri1.com"),X("docEleChildChildChild"));
  317.     docFirstElementChildChild->appendChild(docFirstElementChildChildChild);
  318.     docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:nearerThanPo"), X("http://www.test.com"));
  319.     docFirstElementChildChildChild->setAttributeNS(X("http://testattr.com"), X("attr2"), X("value"));
  320.     docFirstElementChildChildChild->setAttributeNS(X("http://www.test.com"), X("attr1"), X("value"));
  321.     doc->normalizeDocument();
  322.     normalizer->serializeNode(doc);
  323.     cout << "nn";
  324.     //NS1.1 stuff
  325.     //test creating default prefix when NS1 has been set to ""
  326.     noNamespaceEle->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:NS1"), X(""));
  327.     DOMElement *noNamespaceChild = doc->createElementNS(X("http://testclash.com"),X("testing1.1Stuff"));
  328.     noNamespaceEle->appendChild(noNamespaceChild);
  329.     doc->normalizeDocument();
  330.     normalizer->serializeNode(doc);
  331.     noNamespaceChild = doc->createElementNS(X("http://testclash.com"),X("NS1:testing1.1Stuff"));
  332.     noNamespaceEle->appendChild(noNamespaceChild);
  333.     
  334.     noNamespaceChild->setAttributeNS(X("http://www.someRandomUri.com"), X("attr"), X("value"));
  335.     doc->normalizeDocument();
  336.     normalizer->serializeNode(doc);
  337.     //check error conditions
  338.     cout << "error conditions" << endl;
  339.     DOMConfigurationImpl *cImpl = new ((DOMDocumentImpl*)doc) DOMConfigurationImpl();
  340.     ((DOMDocumentImpl*)doc)->setDOMConfiguration(cImpl);
  341.     cImpl->setErrorHandler(normalizer);
  342.     cImpl->setParameter(X("namespaces"), (void*)tmpTrue);
  343.     DOMElement *level1Node = doc->createElement(X("level1Node"));
  344.     docFirstElement->appendChild(level1Node);
  345.     doc->normalizeDocument();
  346.     docFirstElement->removeChild(level1Node);
  347.     docFirstElement->setAttribute(X("level1Attr"), X("level1"));
  348.     doc->normalizeDocument();
  349.     docFirstElement->removeAttribute(X("level1Attr"));
  350.     //cant check this as Xerces does not let us do it
  351.     //    noNamespaceChild->setAttributeNS(X("http://www.someRandomUri.com"), X("xmlns"), X("value"));
  352.     //    doc->normalizeDocument();
  353.     //lets do a sanity test on a comment
  354.     DOMComment *comment = doc->createComment(X("some comment"));
  355.     docFirstElement->appendChild(comment);
  356.     doc->normalizeDocument();
  357.     normalizer->serializeNode(doc);
  358.     cImpl->setParameter(X("comments"), (void*)tmpFalse);
  359.     docFirstElement->appendChild(comment);
  360.     doc->normalizeDocument();
  361.     normalizer->serializeNode(doc);
  362.     //and on a CDATA
  363.     DOMCDATASection *cData = doc->createCDATASection(X("some cdata"));
  364.     docFirstElement->appendChild(cData);
  365.     doc->normalizeDocument();
  366.     normalizer->serializeNode(doc);
  367.     cImpl->setParameter(X("cdata-sections"), (void*)tmpFalse);
  368.     docFirstElement->appendChild(cData);
  369.     doc->normalizeDocument();
  370.     normalizer->serializeNode(doc);
  371.     delete normalizer;
  372.     delete tmpTrue;
  373.     delete tmpFalse;
  374.     return 0;
  375. }