Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.4 KiB

  1. #include "stdinc.h"
  2. #include "prettyformat.h"
  3. #define XML_LINEBREAK (L"\r\n")
  4. #define NUMBER_OF(x) (sizeof(x)/sizeof(*x))
  5. #define XML_SPACE L" "
  6. CString
  7. Padding(int level)
  8. {
  9. CString strRetVal;
  10. static const CString Indentations[] = {
  11. CString(L""),
  12. CString(XML_SPACE),
  13. CString(XML_SPACE XML_SPACE),
  14. CString(XML_SPACE XML_SPACE XML_SPACE),
  15. CString(XML_SPACE XML_SPACE XML_SPACE XML_SPACE),
  16. CString(XML_SPACE XML_SPACE XML_SPACE XML_SPACE XML_SPACE),
  17. CString(XML_SPACE XML_SPACE XML_SPACE XML_SPACE XML_SPACE XML_SPACE),
  18. CString(XML_SPACE XML_SPACE XML_SPACE XML_SPACE XML_SPACE XML_SPACE XML_SPACE)
  19. };
  20. if ( level < NUMBER_OF(Indentations) )
  21. return Indentations[level];
  22. else while ( level-- )
  23. {
  24. strRetVal += L" ";
  25. }
  26. return strRetVal;
  27. }
  28. HRESULT
  29. PrettyFormatXmlDocument2(CSmartPointer<IXMLDOMNode> RootNode, int iLevel)
  30. {
  31. VARIANT_BOOL vtHasChildren;
  32. HRESULT hr;
  33. CSmartPointer<IXMLDOMDocument> ptDocument;
  34. static CString bstLineBreak = L"\r\n";
  35. hr = RootNode->hasChildNodes(&vtHasChildren);
  36. hr = RootNode->get_ownerDocument(&ptDocument);
  37. if ( vtHasChildren == VARIANT_FALSE )
  38. {
  39. //
  40. // End of recursion.
  41. //
  42. }
  43. else
  44. {
  45. //
  46. // For each child of this, append a \r\n combination text node.
  47. //
  48. CSmartPointer<IXMLDOMNode> Child;
  49. hr = RootNode->get_firstChild(&Child);
  50. bool fAppendLastBreaker = false;
  51. while ( Child != NULL )
  52. {
  53. DOMNodeType nt;
  54. CSmartPointer<IXMLDOMNode> nextChild;
  55. hr = Child->get_nodeType(&nt);
  56. //
  57. // We only pretty-format element nodes.
  58. //
  59. if ( nt == NODE_ELEMENT )
  60. {
  61. CSmartPointer<IXMLDOMText> txt;
  62. VARIANT vt;
  63. vt.vt = VT_UNKNOWN;
  64. vt.punkVal = Child;
  65. //
  66. // We need to append a \r\n to the list of siblings as well.
  67. //
  68. fAppendLastBreaker = true;
  69. //
  70. // Insert \r\n before the child, but only if the child is
  71. // not a text node.
  72. //
  73. hr = ptDocument->createTextNode(bstLineBreak + Padding(iLevel + 1), &txt);
  74. hr = RootNode->insertBefore(txt, vt, NULL);
  75. hr = PrettyFormatXmlDocument2(Child, iLevel + 1);
  76. }
  77. if (FAILED(hr = Child->get_nextSibling(&nextChild)))
  78. break;
  79. Child = nextChild;
  80. }
  81. //
  82. // Also append a \r\n to the list of children, to break up
  83. // the </close></close2> tags.
  84. //
  85. if ( fAppendLastBreaker )
  86. {
  87. CSmartPointer<IXMLDOMText> LastBreaker;
  88. hr = ptDocument->createTextNode(bstLineBreak + Padding(iLevel), &LastBreaker);
  89. hr = RootNode->appendChild(LastBreaker, NULL);
  90. }
  91. }
  92. return hr;
  93. }
  94. HRESULT PrettyFormatXmlDocument(CSmartPointer<IXMLDOMDocument2> Document)
  95. {
  96. HRESULT hr = S_OK;
  97. CSmartPointer<IXMLDOMElement> rootElement;
  98. if( FAILED(Document->get_documentElement( &rootElement ) ) ) {
  99. return E_FAIL;
  100. }
  101. hr = PrettyFormatXmlDocument2(rootElement, 0);
  102. return hr;
  103. }