Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Msxml-questions
Message
General information
Forum:
Visual FoxPro
Category:
XML, XSD
Title:
Miscellaneous
Thread ID:
00822934
Message ID:
00823210
Views:
14
You can add the XML declaration (AKA pi) like so:
lcPI = loXML.createProcessingInstruction("xml", "version='1.0'")
loXML.replaceChild(lcPI, loXML.childNodes.item(0))
You can 'pretty-print' the XML using this code:
* Function FormatXML(toXML, tnTabLevel)
* FormatXML() accepts an XML file/string and returns a string 
* with all the nodes indented.  (It's PrettyPrint for XML)
* Simon Ferguson - EPS Software

LPARAMETERS toXML, tnTabLevel
IF EMPTY(tnTabLevel)
	tnTabLevel = 0
ENDIF

LOCAL llMixedTextNode, llHasOnlyATextNode, i, lcFormatXML, lcTempXML
lcFormatXML = ""
lcTempXML = ""	&& VFP 'feature' - Necessary to hold temp XML before recursion of more than 4 levels

** #DEFINE TAB  CHR(9)  && Default IE format
#DEFINE TAB  SPACE(2)  && My preferred format
#DEFINE CR   CHR(13)
#DEFINE CRLF CHR(13)+CHR(10)
#DEFINE DQ   CHR(34)  && doublequote
#DEFINE SQ   CHR(39)  && singlequote
#DEFINE NODE_ELEMENT       	1
#DEFINE NODE_ATTRIBUTE 		2
#DEFINE NODE_TEXT 		3 
#DEFINE NODE_CDATA_SECTION 	4
#DEFINE NODE_ENTITY 		6
#DEFINE NODE_COMMENT 		8
#DEFINE NODE_DOCUMENT 		9
#DEFINE NODE_DOCUMENT_FRAGMENT 	11

** If we passed in a string, convert to DOM object
IF VARTYPE(toXML) = "C"
	LOCAL loXML
	loXML = CREATEOBJECT("MSXML.DomDocument")
	toXML = loXML.LoadXML(toXML)
	RELEASE loXML
ENDIF

WITH toXML
	DO CASE
	CASE .nodeType = NODE_DOCUMENT OR .nodeType = NODE_DOCUMENT_FRAGMENT
		* All child nodes of the document should be at the same level
		* Just iterate over them and recurse with no indent
		FOR i = 0 TO .childNodes.Length- 1
			lcTempXML = lcFormatXML
			lcFormatXML = lcTempXML + FormatXML(.childNodes(i))
		NEXT i

	CASE .nodeType = NODE_TEXT
		* Should render the same way the default IE stylesheet does for mixed content
		* Figure out if we're in some mixed content
		
		* If this text node has any siblings it's in mixed content
		llMixedTextNode = (.parentNode.childNodes.LENGTH > 1)

		* If mixed, indent this string
		IF llMixedTextNode
			lcFormatXML = REPLICATE(TAB, tnTabLevel)
		ENDIF
		* Strip out any tabs and carriage returns from the text
		lcFormatXML = lcFormatXML + TRIM(STRTRAN(STRTRAN(.xml, CRLF, SPACE(1)), TAB, SPACE(1)))

		* If mixed, add carriage return
		IF llMixedTextNode
			lcFormatXML = lcFormatXML + CRLF
		ENDIF

	CASE .nodeType = NODE_ELEMENT
		IF .hasChildNodes
			* If the node has only one child and that child is text
			* don't add carriage return after opening tag
			llHasOnlyATextNode = (.childNodes(0).nodeType = NODE_TEXT) AND (.childNodes.Length = 1)
		ENDIF

		* Open the start tag
		lcFormatXML = REPLICATE(TAB, tnTabLevel) + "<" + .nodeName

		* Recurse over the attributes
		FOR i = 0 TO .Attributes.Length - 1
			lcTempXML = lcFormatXML
			lcFormatXML = lcTempXML + FormatXML(.Attributes(i))
		NEXT i

		* Properly close the start tag based on node's contents
		IF NOT .hasChildNodes
			* No child nodes so it's an empty element
			lcFormatXML = lcFormatXML + "/>" + CRLF

		ELSE
			IF llHasOnlyATextNode
				* Has only text for children - don't add carriage return
				lcFormatXML = lcFormatXML + ">"
			ELSE
				* Has child elements - add carriage return
				lcFormatXML = lcFormatXML + ">" + CRLF
			ENDIF

			* Recurse if there's children
			FOR i = 0 TO .childNodes.Length - 1
				lcTempXML = lcFormatXML
				lcFormatXML = lcTempXML + FormatXML(.childNodes(i), tnTabLevel + 1)
			NEXT i

			* Properly indent and add the end tag
			IF NOT llHasOnlyATextNode
				lcFormatXML = lcFormatXML + REPLICATE(TAB, tnTabLevel)
			ENDIF
			lcFormatXML = lcFormatXML + "</" + .nodeName + ">" + CRLF

		ENDIF

	CASE .nodeType = NODE_COMMENT OR .nodeType = NODE_CDATA_SECTION
		* If comment is on more than one line don't indent
		IF OCCURS(CR, .xml) = 0
			lcFormatXML = REPLICATE(TAB, tnTabLevel)
		ENDIF
		lcFormatXML = lcFormatXML + .xml + CRLF

	CASE .nodeType = NODE_ATTRIBUTE
		* If there are double quotes in the attribute, use single quotes to surround the attribute value
		IF OCCURS(DQ, .text) > 0
			lcFormatXML = SPACE(1) + .nodeName + "=" + SQ + .text + SQ
		ELSE
			lcFormatXML = SPACE(1) + .nodeName + "=" + DQ + .text + DQ
		ENDIF

	CASE .nodeType = NODE_ENTITY
		* Don't expand entities 

	OTHERWISE
		* All other node types should just return their xml
		* These include - entity refs, pi's, notations, doctypes
		lcFormatXML = REPLICATE(TAB, tnTabLevel) + .xml + CRLF

	ENDCASE

ENDWITH

RETURN lcFormatXML
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform