domwriterimpl.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,852 行 · 第 1/5 页

CPP
1,852
字号
            }            else            {                tmpEncoding = docu->getActualEncoding();                if ( tmpEncoding && *tmpEncoding)                {                    fEncodingUsed = tmpEncoding;                }            }        }    }    /**     *  The end-of-line sequence of characters to be used in the XML being     *  written out. The only permitted values are these:     *     . null     *     *  Use a default end-of-line sequence. DOM implementations should choose     * the default to match the usual convention for text files in the     * environment being used. Implementations must choose a default     * sequence that matches one of those allowed by  2.11 "End-of-Line     * Handling".     *     *    CR    The carriage-return character (#xD)     *    CR-LF The carriage-return and line-feed characters (#xD #xA)     *    LF    The line-feed character (#xA)     *     *  The default value for this attribute is null     */    fNewLineUsed = (fNewLine && *fNewLine)? fNewLine : gEOLSeq;    /**     *  get Document Version     */    const DOMDocument *docu = (nodeToWrite->getNodeType() == DOMNode::DOCUMENT_NODE)?                              (const DOMDocument*)nodeToWrite : nodeToWrite->getOwnerDocument();    if (docu)    {        fDocumentVersion = docu->getVersion();    }    fErrorCount = 0;}//// Characters not representable in output encoding,//// 1. CHARACTER DATA (outside of markup)                --- no error//    ordinary character  -> numeric character reference//    '<' and '&'         -> &lt; and &amp;//// 2. Within MARKUP, but outside of attributes//    reported as an error                                 --- ERROR//    markup://           start tag                                  done//           end tag                                    done//           empty element tag                          done//           entity references                          done//           character references    // REVISIT//           comments                                   done//           CDATA section delimiters                   done, done//           document type declarartions                done//           processing instructions (PI)               done//// 3. With in ATTRIBUTE//    -> numeric character reference//    no quotes                        -> in quotes//    with quotes, no apostrophe       -> in apostrophe//    with quotes and apostrophe       -> in quotes and &quot;//// 4. CDATA sections//    "split_cdata_section"  true                      --- char ref//                           false                     ---      ERROR//// ---------------------------------------------------------------------------//  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.// ---------------------------------------------------------------------------void DOMWriterImpl::processNode(const DOMNode* const nodeToWrite, int level){    // Get the name and value out for convenience    const XMLCh*    nodeName = nodeToWrite->getNodeName();    const XMLCh*    nodeValue = nodeToWrite->getNodeValue();    unsigned long   lent = XMLString::stringLen(nodeValue);    switch (nodeToWrite->getNodeType())    {    case DOMNode::TEXT_NODE:        {            if (checkFilter(nodeToWrite) != DOMNodeFilter::FILTER_ACCEPT)                break;            if (getFeature(FORMAT_PRETTY_PRINT_ID))            {                lineFeedInTextNodePrinted = false;                lastWhiteSpaceInTextNode = 0;                if(XMLString::isAllWhiteSpace(nodeValue))                {                    // skips whitespace-only text nodes unless whitespace-in-element is set.                    if (!getFeature(WHITESPACE_IN_ELEMENT_CONTENT_ID))                    {                        break;                    }                    else                            {                        //                        // we need to trace if newline(s) have been printed out                        // to avoid generate extra newline for pretty printing,                        // as well as the number of whitespaces after the last                        // newline character to do indentation properly.                        //                        int pos = XMLString::lastIndexOf(nodeValue, chLF);                        if (-1 != pos)                        {                            lineFeedInTextNodePrinted = true;                            lastWhiteSpaceInTextNode = lent - pos;                        }                        else                        {                            // for those platforms using chCR alone as                            // a newline character                            pos = XMLString::lastIndexOf(nodeValue, chCR);                            if (-1 != pos)                            {                                lineFeedInTextNodePrinted = true;                                lastWhiteSpaceInTextNode = lent - pos;                            }                        }                    }                }            }            setURCharRef();      // character data            fFormatter->formatBuf(nodeValue, lent, XMLFormatter::CharEscapes);            break;        }    case DOMNode::PROCESSING_INSTRUCTION_NODE:        {            if (checkFilter(nodeToWrite) != DOMNodeFilter::FILTER_ACCEPT)                break;            if(level == 1)                printNewLine();            printNewLine();            printIndent(level);            TRY_CATCH_THROW            (                *fFormatter << XMLFormatter::NoEscapes << gStartPI << nodeName;                if (lent > 0)                {                    *fFormatter << chSpace << nodeValue;                }                *fFormatter << gEndPI;                ,true            )            break;        }    case DOMNode::DOCUMENT_NODE: // Not to be shown to Filter        {            // output BOM if needed            processBOM();                                  setURCharRef();            const DOMDocument *docu = (const DOMDocument*)nodeToWrite;                    //[23] XMLDecl      ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'            //[24] VersionInfo  ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')            //[80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName            //[32] SDDecl       ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'))            //            if (getFeature(XML_DECLARATION)) {                const XMLCh* versionNo = (docu->getVersion()) ? docu->getVersion() : gXMLDecl_ver10;                *fFormatter << gXMLDecl_VersionInfo << versionNo << gXMLDecl_separator;                // use the encoding resolved in initSession()                *fFormatter << gXMLDecl_EncodingDecl << fEncodingUsed << gXMLDecl_separator;                const XMLCh* st = (docu->getStandalone())? XMLUni::fgYesString : XMLUni::fgNoString;                *fFormatter << gXMLDecl_SDDecl << st << gXMLDecl_separator;                                *fFormatter << gXMLDecl_endtag;            }            DOMNodeSPtr child = nodeToWrite->getFirstChild();            while( child != 0)            {                processNode(child, level);                child = child->getNextSibling();            }            printNewLine();            break;        }    case DOMNode::DOCUMENT_FRAGMENT_NODE:        {                       setURCharRef();            DOMNode *child = nodeToWrite->getFirstChild();            while( child != 0)            {                processNode(child, level);                child = child->getNextSibling();            }            printNewLine();            break;        }    case DOMNode::ELEMENT_NODE:        {            DOMNodeFilter::FilterAction filterAction = checkFilter(nodeToWrite);            if ( filterAction == DOMNodeFilter::FILTER_REJECT)                break;            if (!lineFeedInTextNodePrinted)            {                if(level == 1)                    printNewLine();                printNewLine();            }            else            {                lineFeedInTextNodePrinted = false;            }            printIndent(level);            //track the line number the current node begins on            int nodeLine = fCurrentLine;            // add an entry in the namespace stack            RefHashTableOf<XMLCh>* namespaceMap=NULL;            if ( filterAction == DOMNodeFilter::FILTER_ACCEPT)            {                //           this element    attributes   child elements                // accept        yes             yes           yes                // skip          no              no            yes                //                TRY_CATCH_THROW                (                // The name has to be representable without any escapes                    *fFormatter  << XMLFormatter::NoEscapes                                 << chOpenAngle << nodeName;                    ,true                )                // Output any attributes on this element                setURCharRef();                DOMNamedNodeMap *attributes = nodeToWrite->getAttributes();                int attrCount = attributes->getLength();                // check if the namespace for the current node is already defined                const XMLCh* prefix = nodeToWrite->getPrefix();                const XMLCh* uri = nodeToWrite->getNamespaceURI();                if(uri && uri[0])                {                    if(prefix==0 || prefix[0]==0)                        prefix=XMLUni::fgZeroLenString;                    bool bPrefixDeclared=false;                    for(int i=fNamespaceStack->size()-1;i>=0;i--)                    {                        RefHashTableOf<XMLCh>* curNamespaceMap=fNamespaceStack->elementAt(i);                        const XMLCh* thisUri=curNamespaceMap->get((void*)prefix);                        if(thisUri && XMLString::equals(thisUri,nodeToWrite->getNamespaceURI()))                        {                            bPrefixDeclared=true;                            break;                        }                    }                    if(!bPrefixDeclared)                    {                        if(namespaceMap==NULL)                        {                            namespaceMap=new (fMemoryManager) RefHashTableOf<XMLCh>(12, false, fMemoryManager);                            fNamespaceStack->addElement(namespaceMap);                        }                        namespaceMap->put((void*)prefix,(XMLCh*)nodeToWrite->getNamespaceURI());                        *fFormatter  << XMLFormatter::NoEscapes                                     << chSpace << XMLUni::fgXMLNSString;                        if(!XMLString::equals(prefix,XMLUni::fgZeroLenString))                            *fFormatter  << chColon << prefix;                        *fFormatter  << chEqual << chDoubleQuote                                     << XMLFormatter::AttrEscapes                                     << nodeToWrite->getNamespaceURI()                                     << XMLFormatter::NoEscapes                                     << chDoubleQuote;                    }                }                bool discard = getFeature(DISCARD_DEFAULT_CONTENT_ID);                for (int i = 0; i < attrCount; i++)                {                    DOMAttrSPtr  attribute = (DOMAttr*)attributes->item(i);                    // Not to be shown to Filter                    //                    //"discard-default-content"                    //    true                    //    [required] (default)                    //    Use whatever information available to the implementation                    //  (i.e. XML schema, DTD, the specified flag on Attr nodes,                    //  and so on) to decide what attributes and content should be                    //  discarded or not.                    //  Note that the specified flag on Attr nodes in itself is                    //  not always reliable, it is only reliable when it is set                    //  to false since the only case where it can be set to false                    //  is if the attribute was created by the implementation.                    //  The default content won't be removed if an implementation                    //  does not have any information available.                    //    false                    //    [required]                    //    Keep all attributes and all content.                    //                    if (discard && !((DOMAttr*)attribute )->getSpecified())                        continue;                    //                    //  Again the name has to be completely representable. But the                    //  attribute can have refs and requires the attribute style                    //  escaping.                    //                    // if this attribute is a namespace declaration, add it to the namespace map for the current level                    const XMLCh* ns = attribute->getNamespaceURI();                    if (ns != 0 )                    {                        if(XMLString::equals(ns, XMLUni::fgXMLNSURIName))                         {                            if(namespaceMap==NULL)                            {                                namespaceMap=new (fMemoryManager) RefHashTableOf<XMLCh>(12, false, fMemoryManager);                                fNamespaceStack->addElement(namespaceMap);                            }			                const XMLCh* nsPrefix = attribute->getLocalName();                            if(XMLString::equals(attribute->getNodeName(),XMLUni::fgXMLNSString))								nsPrefix = XMLUni::fgZeroLenString;							if(namespaceMap->containsKey((void*)nsPrefix))								continue;                            namespaceMap->put((void*)attribute->getLocalName(),(XMLCh*)attribute->getNodeValue());                        }                        else if(!XMLString::equals(ns, XMLUni::fgXMLURIName))                         {                            // check if the namespace for the current node is already defined                            const XMLCh* prefix = attribute->getPrefix();                            if(prefix && prefix[0])                            {                                bool bPrefixDeclared=false;                                for(int i=fNamespaceStack->size()-1;i>=0;i--)                                {                                    RefHashTableOf<XMLCh>* curNamespaceMap=fNamespaceStack->elementAt(i);                                    const XMLCh* thisUri=curNamespaceMap->get((void*)prefix);                                    if(thisUri && XMLString::equals(thisUri,attribute->getNamespaceURI()))                                    {                                        bPrefixDeclared=true;                                        break;                                    }                                }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?