I have an instance of MSXML2.DomDocument.
I wave to save it, with indenting.
This code works, but does not indent:
var dom = new ActiveXObject("MSXML2.DomDocument");
// fiddle with dom here
dom.save(filename);
I think I can use an MXXMLWriter object to inject indenting.
How?
This oughta do it.
function saveDomWithIndent(dom, filename) {
var writer = new ActiveXObject("MSXML2.MXXMLWriter"),
reader = new ActiveXObject("MSXML2.SAXXMLReader"),
fso = new ActiveXObject("Scripting.FileSystemObject"),
textStream = fso.CreateTextFile(filename, true);
writer.indent = true;
writer.omitXMLDeclaration = true;
reader.contentHandler = writer;
reader.parse(dom);
textStream.Write(writer.output);
textStream.Close();
}
Use it like this:
var root, node, newnode,
dom = new ActiveXObject("MSXML2.DOMDocument.6.0");
dom.async = false;
dom.resolveExternals = false;
dom.load(fullpath);
root = dom.documentElement;
node = root.selectSingleNode("/root/node1");
if (node !== null) {
newnode = dom.createElement('node2');
newnode.text = "hello";
root.appendChild(newnode);
saveDomWithIndent(dom, fullpath);
}
I could not figure out how to adjust the indent level. It always indents with a tab.
There is another way to prettifying xml outputs, plus you can adjust the indent level manually : XSL.
var adSaveCreateOverWrite = 2
var Indent = new ActiveXObject("MSXML2.DomDocument");
Indent.async = false;
Indent.resolveExternals = false;
Indent.load("indent.xsl");
var Doc = new ActiveXObject("MSXML2.DomDocument");
Doc.async = false;
Doc.resolveExternals = false;
Doc.load("dirty.xml");
with(new ActiveXObject("ADODB.Stream")){
Charset = "utf-8";
Open();
WriteText(Doc.transformNode(Indent));
SaveToFile("pretty.xml", adSaveCreateOverWrite);
Close();
}
indent.xsl
<?xml version="1.0" encoding="ISO-8859-15"?>
<!-- http://x443.wordpress.com/2011/page/34/ -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="normalize-space(.)" />
</xsl:template>
<xsl:template match="*">
<xsl:param name="indent" select="''"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="$indent" />
<xsl:copy>
<xsl:apply-templates select="@*|*|text()">
<xsl:with-param name="indent" select="concat($indent, ' ')"/>
</xsl:apply-templates>
</xsl:copy>
<xsl:if test="count(../*)>0 and ../*[last()]=.">
<xsl:text>
</xsl:text>
<xsl:value-of select="substring($indent,3)" />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
A bit overcomplicated ??
Did not work for me (in WSH / cscript) - error and empty file.
Then found you can use save method - my new filter out VS (empty) C++ filters script
var arg = WScript.arguments(0);
var doc = readFile(arg);
var xml = doc.documentElement.firstChild;
do {
var filters = {};
while (xml && xml.nodeName != "ItemGroup") xml = xml.nextSibling;
if (!xml) break;
var xml2 = xml.firstChild;
while (xml2 && (xml2.nodeName == "ClInclude" || xml2.nodeName == "ClCompile"))
{
var path = xml2.attributes.getNamedItem("Include").nodeValue;
var filter = xml2.firstChild;
if (filter != null) {
filter = filter.text;
}
if (filters[path])
{ //WScript.Echo(path + " had " + filter);
if (!filter)
{
var prev = xml2.previousSibling;
xml.removeChild(xml2);
xml2 = prev;
}
} else {
if (filter != null) {
filters[path] = filter;
}
}
xml2 = xml2.nextSibling;
}
xml = xml.nextSibling;
} while (xml);
doc.save(arg);
function readFile(filename)
{
var xml = new ActiveXObject("Msxml2.DOMDocument.6.0");
xml.async = false;
xml.resolveExternals = false;
xml.async = false;
xml.load(arg);
return xml;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With