2011-06-19 114 views
3

Visual Basic 6でMSXML 3.0を使用して、アプリケーションの構成を格納および取得しています。ルートオブジェクトは、テキストの単一の非常に長い行としてレンダリングされるファイルをXMLに結果DOMDocumentを保存する場合:MSXMLにインデントと改行を使用してXML出力をフォーマットさせる

<?xml version="1.0"?> 
<!--WORKAPP 2011 Configuration file--> 
<profile version="1.0"><frmPlan><left>300</left><top>300</top><width>24600</width><height>13575</height></frmPlan><preferences><text1/><text2/><text3/><background_color/><grid-major-step-x>50</grid-major-step-x><grid-major-step-y>50</grid-major-step-y></preferences></profile> 

インデントや改行と結果のXMLファイルをフォーマットするMSXMLを強制することは可能ですか?

答えて

2

this other question on SOとその回答のC++コードをご覧ください。しかし、それはあまりにも多くの仕事です。あなたは設定ファイルを保存しているだけだと言っています。だから、XSLT変換を使用します。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:strip-space elements="*"/> 
    <xsl:output indent="yes"/> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

ADODB.Streamに、ではないDOMに出力することを忘れないでください。 DOMに出力すると、XSLTシリアライザは無視されます。

+0

これをMSXMLに格納する場所について何かを含めることができますか? –

+0

@MattMcNabb - (pretty.xslのような)XSLTファイルにコードを入れてから、[Microsoft 'msxsl.exe'コマンドラインユーティリティ(http:// www。 microsoft.com/en-us/download/details.aspx?id=21714)または他のXSLTプロセッサまた、[変換を行うためにMSXML APIを使用する]こともできます(https://msdn.microsoft.com/en-us/library/ms766561(v = vs.85).aspx)。 – Lumi

+0

ありがとうございます。しかし、出力が期待どおりに出ていないと私は[新しい質問を開始した](http://stackoverflow.com/questions/28133229/xslt-indent-not-working-with-msxml) –

4

configのような小さなファイルの場合、おそらくXSLを使用するオーバーヘッドは重要ではありません。大規模なファイルやWebサービスのサーバー側のような小さなファイルを処理する場合、SAXの機能は重要です。まず、ヘビー級DOMを使用しないでください。

Private Sub FormatDocToFile(ByVal Doc As MSXML2.DOMDocument, _ 
          ByVal FileName As String) 
    'Reformats the DOMDocument "Doc" into an ADODB.Stream 
    'and writes it to the specified file. 
    ' 
    'Note the UTF-8 output never gets a BOM. If we want one we 
    'have to write it here explicitly after opening the Stream. 
    Dim rdrDom As MSXML2.SAXXMLReader 
    Dim stmFormatted As ADODB.Stream 
    Dim wtrFormatted As MSXML2.MXXMLWriter 

    Set stmFormatted = New ADODB.Stream 
    With stmFormatted 
     .Open 
     .Type = adTypeBinary 
     Set wtrFormatted = New MSXML2.MXXMLWriter 
     With wtrFormatted 
      .omitXMLDeclaration = False 
      .standalone = True 
      .byteOrderMark = False 'If not set (even to False) then 
            '.encoding is ignored. 
      .encoding = "utf-8" 'Even if .byteOrderMark = True 
            'UTF-8 never gets a BOM. 
      .indent = True 
      .output = stmFormatted 
      Set rdrDom = New MSXML2.SAXXMLReader 
      With rdrDom 
       Set .contentHandler = wtrFormatted 
       Set .dtdHandler = wtrFormatted 
       Set .errorHandler = wtrFormatted 
       .putProperty "http://xml.org/sax/properties/lexical-handler", _ 
          wtrFormatted 
       .putProperty "http://xml.org/sax/properties/declaration-handler", _ 
          wtrFormatted 
       .parse Doc 
      End With 
     End With 
     .SaveToFile FileName 
     .Close 
    End With 
End Sub 
3

おそらく、この回答はあなたの特定のケースで役立つことはありませんが、一般的には役に立つかもしれません。それは、文書があまり変更されずにロードされ、保存されるケースを考慮する。 DomDocumentpreserveWhitespaceの属性を持ち、最初はFalseに設定されています。 をloadの前に設定すると、元のファイルと同じ字下げを使用して保存されます。ここで

Set txt = doc.createTextNode(vbCrLf & " ") 
Call node.parentNode.insertBefore(txt, node) 
+0

これは実際には非常に有用だった。私は提案されたxslt変換のどれもが6.0より前のmsxmlのバージョンでは動作しないと信じています。これには多くの時間を費やしましたが、文書化された理由をまだ見つけていませんが、インデント "フラグは6.0より前にサポートされています –

1

は、DOMオブジェクトと文字列上で動作短くインデントユーティリティ関数です:1、テキストノードを作成し、要素間の新しいライン・アンド・スペースを作成するためにそれらを挿入し、このようなことがあり、手動でインデントを追加するには

フォーマットされた文字列を出力します。ファイル処理(utf-8)はそのスコープの外に置かれます。 ADODBストリームを使用せず、プロジェクト参照にMSXMLを必要としません。

Public Function FormatXmlIndent(vDomOrString As Variant, sResult As String) As Boolean 
    Dim oWriter   As Object ' MSXML2.MXXMLWriter 

    On Error GoTo QH 
    Set oWriter = CreateObject("MSXML2.MXXMLWriter") 
    oWriter.omitXMLDeclaration = True 
    oWriter.indent = True 
    With CreateObject("MSXML2.SAXXMLReader") 
     Set .contentHandler = oWriter 
     '--- keep CDATA elements 
     .putProperty "http://xml.org/sax/properties/lexical-handler", oWriter 
     .parse vDomOrString 
    End With 
    sResult = oWriter.output 
    '--- success 
    FormatXmlIndent = True 
    Exit Function 
QH: 
End Function 

何が(無効なXMLなど)を失敗したので、もし...この

sXml = ReadTextFile("doc.xml") 
    FormatXmlIndent sXml, sXml 

同じように使用できsXmlはまだ元の書式設定されていない入力を保持しています。

関連する問題