void HtmlParser::outputHtmlNode(MemBuffer& buffer, const HtmlNode* pNode) { int attributeIndex = 0; if(pNode == NULL) return; switch(pNode->type) { case NODE_CONTENT: if(pNode->flags & FLAG_CDATA_BLOCK) { buffer.appendText("<![CDATA[", 9); buffer.appendText(pNode->text); buffer.appendText("]]>", 3); } else buffer.appendText(pNode->text); break; case NODE_START_TAG: buffer.appendChar('<'); buffer.appendText(pNode->tagName); if(pNode->attributeCount > 0) buffer.appendChar(' '); for(attributeIndex = 0; attributeIndex < pNode->attributeCount; attributeIndex++) { const HtmlAttribute* pAttribute = getAttribute(pNode, attributeIndex); buffer.appendText(pAttribute->name); if(pAttribute->value) { bool hasQuoteChar = (strchr(pAttribute->value, '\"') != NULL); buffer.appendChar('='); buffer.appendChar(hasQuoteChar ? '\'' : '\"'); buffer.appendText(pAttribute->value); buffer.appendChar(hasQuoteChar ? '\'' : '\"'); } if(attributeIndex < pNode->attributeCount - 1) buffer.appendChar(' '); } if(pNode->attributeCount == 0 && pNode->text) //比如 <!DOCTYPE ...> { buffer.appendChar(' '); buffer.appendText(pNode->text); } if(pNode->flags & FLAG_SELF_CLOSING_TAG) buffer.appendText(" /"); //自封闭 buffer.appendChar('>'); break; case NODE_END_TAG: buffer.appendText("</"); buffer.appendText(pNode->tagName); buffer.appendChar('>'); break; case NODE_REMARKS: buffer.appendText("<!--"); buffer.appendText(pNode->text); buffer.appendText("-->"); break; case NODE_UNKNOWN: default: fprintf(stderr, "HtmlParser.outputHtmlNode(): NODE_UNKNOWN\n"); break; } //end switch }