2012-06-21 14 views

Respuesta

6

Esto 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(); 
} 

utilizar de esta manera:

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); 
} 

no podía encontrar la manera de ajustar el nivel de sangría. Siempre sangra con una pestaña .

1

Hay otra manera de embellecer salidas XML, además de que puede ajustar manualmente el nivel de sangría: 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>&#xa;</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>&#xa;</xsl:text> 
     <xsl:value-of select="substring($indent,3)" /> 
    </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 
+0

agradable. Esto nos lleva a la siguiente pregunta: ¿puedo usar un XSL integrado, una de las hojas XSL integradas en msxml6.dll, para realizar la sangría? Supongo que sería necesario extraer mediante programación el XSL y luego aplicarlo. – Cheeso

+0

@ Cheez Lo siento, no entendí exactamente lo que quieres decir. En realidad, estoy usando la instancia 'FreeThreadedDomDocument' como un objeto estático que se almacena en el ámbito de aplicación (inicializado en el evento' Application_OnStart') con ASP clásico. Esto evita las transacciones recurrentes para cada transformación. –

+0

Sé que esta es una corriente de comentarios obsoletos ahora, pero ... para explicar lo que quise decir antes: Creo que msxml incluye al menos un XSLT incorporado. ver http://stackoverflow.com/questions/9463402/default-xml-stylesheet-in-chrome La razón por la que pregunto es, sería más simple si pudiera usar un xslt integrado en lugar de incrustar mi propia hoja personalizada. – Cheeso

-1

Si no desea utilizar XSL, que sólo podría insertar vbcrlfs. Cada ">" debe seguir a vbcrlf, excepto cuando ">" va seguido de un número. Luego, cree un nuevo archivo xml a partir de esa cadena, ahora tiene nuevas líneas y sangrías. VBA msaccess:

Dim objDom As DOMDocument 
Set objDom = CreateObject("MSXML2.DOMDocument") 

crear documentos con objDom.append, y luego jugar con una cuerda (mi xml tenía sólo números):

ss = objectDom.XML 
For i = 1 To Len(ss) 
c = Mid(ss, i, 1) 
    If InStr(1, Mid(ss, i, 1), ">") > 0 Then 
     a = Asc(Mid(ss, i + 1, 1)) 
     If a < 48 Or a > 57 Then 
      ss1 = Mid(ss, 1, i) 
      ss2 = Mid(ss, i + 1, Len(ss)) 
      ss = Mid(ss, 1, i) & vbCrLf & Mid(ss, i + 1, Len(ss)) 
     End If 
    End If 

Next i 

objDom.loadXML ss 
objDom.Save (file_path) 
+0

La pregunta es sobre js (var vs dim) ... en vba considera usar la opción explicit. Lo siguiente fue útil para mí, en caso de que alguien más lo esté buscando: http://www.vb-helper.com/howto_formatted_xml_document.html –

Cuestiones relacionadas