none
XMLファイルの出力 RRS feed

  • 質問

  • 以下の様なXMLをファイルに出力したいです。

    <?xml version="1.0" encoding="Shift_JIS"?>
    <HOGE name="ホゲ">
     <HOGEID>1001</HOGEID>
     <FIELDS>
      <FIELD name="区域" >区域A</FIELD>
      <FIELD name="告示番号" >260123</FIELD>
      <FIELD name="市町村名" >綾部市</FIELD>
      <FIELD name="都市名" ></FIELD>
     </FIELDS>
    </HOGE>
    まずXmlTextWriterを使用する方法が考えられますが、XmlTextWriterだと改行もインデントもしてくれません。

    また「<FIELD name="区域" >区域A</FIELD>」の様なデータをどうやって出力していいかも分かりません。

    次にサンプルプログラムとして

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
     Dim dSet As DataSet = New DataSet("生物")
     Dim dTbl As DataTable
     Dim sWrite As IO.StreamWriter
     dTbl = dSet.Tables.Add("リス")
     dTbl.Columns.Add("ID", Type.GetType("System.Int32"))
     dTbl.Columns.Add("名前", Type.GetType("System.String"))
     dTbl.Rows.Add(New Object() {1, "シマリス"})
     dTbl.Rows.Add(New Object() {2, "キタリス"})
     dTbl.Rows.Add(New Object() {3, "ニホンリス"})
     sWrite = New IO.StreamWriter("D:\Sample.xml", False, System.Text.Encoding.Default)
     dSet.WriteXml(sWrite)
     MessageBox.Show("Sample.xmlに出力しました", "通知")
    End Sub

    があります。出力結果は以下の通りです。

    <生物>
     <リス>
      <ID>1</ID>
      <名前>シマリス</名前>
     </リス>
     <リス>
      <ID>2</ID>
      <名前>キタリス</名前>
     </リス>
     <リス>
      <ID>3</ID>
      <名前>ニホンリス</名前>
     </リス>
    </生物>

    改行もインデントもされていて格好いいですが、

    <?xml version="1.0" encoding="Shift_JIS"?>
    が出力されませんし、先程と同様に「<FIELD name="区域" >区域A</FIELD>」の様なデータをどうやって出力していいかも分かりません。

    1.XmlTextWriterを使う方法

    2.DataSetを使う方法

    どちらでもいいので、最初に載せたXMLに近いファイルに出力する方法が知りたいです。

    ご回答の程よろしくお願いします。

    2010年12月21日 23:32

回答

  • LINQ to XML を使って出力するという手段もあります。

    Module Module1
    
      Sub Main()
        Dim document As XDocument = New XDocument()
        document.Declaration = New XDeclaration("1.0", "utf-8", Nothing)
    
        'HOGE ノード追加
        Dim hoge As XElement = New XElement("HOGE")
        document.Add(hoge)
    
        'HOGE ノードに name 属性を追加
        hoge.Add(New XAttribute("name", "ホゲ"))
    
        'HOGE ノードに HOGEID ノード追加
        Dim hogeId As XElement = New XElement("HOGEID")
        hogeId.Add(1001)
        hoge.Add(hogeId)
    
        'HOGE ノードに FIELDS ノード追加
        Dim fields As XElement = New XElement("FIELDS")
        hoge.Add(fields)
    
        'FIELDS ノードに FIELD ノード "区域" を追加
        Dim kuiki As XElement = New XElement("FIELD")
        kuiki.Add(New XAttribute("name", "区域"))
        kuiki.Add("区域A")
        fields.Add(kuiki)
    
        'FIELDS ノードに FIELD ノード "告示番号" を追加
        Dim kokuji As XElement = New XElement("FIELD")
        kokuji.Add(New XAttribute("name", "告示番号"))
        kokuji.Add(260123)
        fields.Add(kokuji)
    
        'FIELDS ノードに FIELD ノード "市町村名" を追加
        Dim sityoson As XElement = New XElement("FIELD")
        sityoson.Add(New XAttribute("name", "市町村名"))
        sityoson.Add("綾部市")
        fields.Add(sityoson)
    
        'FIELDS ノードに FIELD ノード "市町村名" を追加
        Dim city As XElement = New XElement("FIELD")
        city.Add(New XAttribute("name", "都市名"))
        city.Add("")
        fields.Add(city)
    
        Console.WriteLine(document.Declaration)
        Console.WriteLine(document.ToString())
        Console.ReadLine()
      End Sub
    
    End Module
    
    

    参考までに。

     


    なかむら(http://d.hatena.ne.jp/griefworker)
    2010年12月22日 2:12
  • XmlWriterSettingsにおいて、エンコーディングの文字列の大文字小文字の指定の方法は

    申し訳ありませんが私は存じません。

    なかむらさんの仰っている方法であれば、XDeclarationに対して指定するエンコードを

    大文字にすることで実現可能でした。

    document.Declaration = New XDeclaration("1.0", "Shift_JIS", Nothing)
    

    ・・・

    Using writerWriter As New StreamWriter("C:\data.xml", False, System.Text.Encoding.GetEncoding("shift_jis"))
      writerWriter.WriteLine(document.Declaration)
      writerWriter.WriteLine(document.ToString())
    End Using
    

    2010年12月22日 3:13

すべての返信

  • .NET 2.0 以降なら、XmlWriter.Create に渡す XmlWriterSettings の Indent プロパティなどで指定できます。.NET 1.1 で XmlTextWriter を使うなら、Formatting プロパティなどを使います。
    2010年12月21日 23:41
  • VBのようなので、XMLリテラル という機能も使えるのかもしれません。
    2010年12月22日 0:26
  • http://msdn.microsoft.com/ja-jp/library/system.xml.xmlwritersettings.indent(VS.80).aspx

    と言うページを見つけたので、そこに載っていたサンプル

    Imports System
    Imports System.IO
    Imports System.Xml
    Imports System.Text
    Imports Microsoft.VisualBasic

    Public Class Sample

      Public Shared Sub Main()

        Dim writer As XmlWriter = Nothing

        Try

          ' Create an XmlWriterSettings object with the correct options.
          Dim settings As XmlWriterSettings = New XmlWriterSettings()
          settings.Indent = True
          settings.IndentChars = (ControlChars.Tab)
          settings.OmitXmlDeclaration = False

          ' Create the XmlWriter object and write some content.
          writer = XmlWriter.Create("D:\data.xml", settings)
          writer.WriteStartElement("book")
          writer.WriteElementString("item", "tesing")
          writer.WriteEndElement()

          writer.Flush()

        Finally
          If Not (writer Is Nothing) Then
            writer.Close()
          End If
        End Try

      End Sub
    End Class

    を使って

    <?xml version="1.0" encoding="utf-8"?>
    <book>
        <item>tesing</item>
    </book>

    と言うファイルを出力する事には成功しました。

    しかし、「<FIELD name="区域" >区域A</FIELD>」の様なデータをどうやって出力していいかが未だ分かりません。

    ご回答の程よろしくお願いします。

    2010年12月22日 0:27
  • 属性を出力するには、WriteAttributeString メソッドを使用します。
    2010年12月22日 0:34
  • XmlTextWriter を使った XML の出力方法は次の記事が参考になると思います。

    http://www.atmarkit.co.jp/fdotnet/easyxml/easyxml02/easyxml02_02.html

    http://www.atmarkit.co.jp/fdotnet/easyxml/easyxml02/easyxml02_03.html

     


    なかむら(http://d.hatena.ne.jp/griefworker)
    2010年12月22日 0:36
  • WriteAttributeString 以外にも、WriteString も使うことになると思います。

    あと、要素値が無い場合でも完全な終了タグが必要なようなので、

    WriteFullEndElement を使います。以下要素値が無い場合のEndElementの挙動例。

    ※WriteFullEndElement ・・・ <hoge></hoge>

    ※WriteEndElement ・・・ <hoge />

    実際は要素はループで設定したりとあるでしょうが、以下のような感じでしょうか。

     

    ' Create the XmlWriter object and write some content.
    writer = XmlWriter.Create("C:\data.xml", settings)
    ' HOGE - Start
    writer.WriteStartElement("HOGE")
    writer.WriteAttributeString("name", "ホゲ")
    ' HOGEID 
    writer.WriteElementString("HOGEID", "1001")
    ' FIELDS - Start
    writer.WriteStartElement("FIELDS")
    ' FIELD - 区域
    writer.WriteStartElement("FIELD")
    writer.WriteAttributeString("name", "区域")
    writer.WriteString("区域A")
    writer.WriteFullEndElement()
    ' FIELD - 告示番号
    writer.WriteStartElement("FIELD")
    writer.WriteAttributeString("name", "告示番号")
    writer.WriteString("260123")
    writer.WriteFullEndElement()
    ' FIELD - 告示番号
    writer.WriteStartElement("FIELD")
    writer.WriteAttributeString("name", "市町村名")
    writer.WriteString("綾部市")
    writer.WriteFullEndElement()
    ' FIELD - 告示番号
    writer.WriteStartElement("FIELD")
    writer.WriteAttributeString("name", "都市名")
    writer.WriteFullEndElement()
    ' FIELDS - End
    writer.WriteFullEndElement()
    ' HOGE - End
    writer.WriteFullEndElement()
    
    

     

    <?xml version="1.0" encoding="utf-8"?>
    <HOGE name="ホゲ">
    	<HOGEID>1001</HOGEID>
    	<FIELDS>
    		<FIELD name="区域">区域A</FIELD>
    		<FIELD name="告示番号">260123</FIELD>
    		<FIELD name="市町村名">綾部市</FIELD>
    		<FIELD name="都市名"></FIELD>
    	</FIELDS>
    </HOGE>

     

    • 編集済み honefai 2010年12月22日 1:09 追記:WriteFullEndElement関連
    2010年12月22日 1:03
  • honefaiさんに教えて貰ったコードを使用して、honefaiさんの書き込みの最後にもあるXMLファイルを出力する事に成功しました。

    後、欲を言えば<?xml version="1.0" encoding="utf-8"?>ではなくて、<?xml version="1.0" encoding="Shift_JIS"?>にしたいのですが、ご回答の程よろしくお願いします。


    2010年12月22日 1:48
  • XmlWriterSettings の Encoding に指定しましょう。

    ' Create an XmlWriterSettings object with the correct options. 
    Dim settings As XmlWriterSettings = New XmlWriterSettings()
    settings.Indent = True
    settings.IndentChars = (ControlChars.Tab)
    settings.OmitXmlDeclaration = False
    settings.Encoding = Encoding.GetEncoding("Shift_JIS")
    
    

    2010年12月22日 1:56
  • honefaiさんに教えて貰ったコードを使用して、encodingの値をシフトJISに出来ました。

    ただ、欲を言えば「encoding="shift_jis"」と小文字になってしまうので、指定した値に出来るのならばしたいです。(Javaは出来るみたいです)

    ご回答の程よろしくお願いします。

    2010年12月22日 2:09
  • LINQ to XML を使って出力するという手段もあります。

    Module Module1
    
      Sub Main()
        Dim document As XDocument = New XDocument()
        document.Declaration = New XDeclaration("1.0", "utf-8", Nothing)
    
        'HOGE ノード追加
        Dim hoge As XElement = New XElement("HOGE")
        document.Add(hoge)
    
        'HOGE ノードに name 属性を追加
        hoge.Add(New XAttribute("name", "ホゲ"))
    
        'HOGE ノードに HOGEID ノード追加
        Dim hogeId As XElement = New XElement("HOGEID")
        hogeId.Add(1001)
        hoge.Add(hogeId)
    
        'HOGE ノードに FIELDS ノード追加
        Dim fields As XElement = New XElement("FIELDS")
        hoge.Add(fields)
    
        'FIELDS ノードに FIELD ノード "区域" を追加
        Dim kuiki As XElement = New XElement("FIELD")
        kuiki.Add(New XAttribute("name", "区域"))
        kuiki.Add("区域A")
        fields.Add(kuiki)
    
        'FIELDS ノードに FIELD ノード "告示番号" を追加
        Dim kokuji As XElement = New XElement("FIELD")
        kokuji.Add(New XAttribute("name", "告示番号"))
        kokuji.Add(260123)
        fields.Add(kokuji)
    
        'FIELDS ノードに FIELD ノード "市町村名" を追加
        Dim sityoson As XElement = New XElement("FIELD")
        sityoson.Add(New XAttribute("name", "市町村名"))
        sityoson.Add("綾部市")
        fields.Add(sityoson)
    
        'FIELDS ノードに FIELD ノード "市町村名" を追加
        Dim city As XElement = New XElement("FIELD")
        city.Add(New XAttribute("name", "都市名"))
        city.Add("")
        fields.Add(city)
    
        Console.WriteLine(document.Declaration)
        Console.WriteLine(document.ToString())
        Console.ReadLine()
      End Sub
    
    End Module
    
    

    参考までに。

     


    なかむら(http://d.hatena.ne.jp/griefworker)
    2010年12月22日 2:12
  • XmlWriterSettingsにおいて、エンコーディングの文字列の大文字小文字の指定の方法は

    申し訳ありませんが私は存じません。

    なかむらさんの仰っている方法であれば、XDeclarationに対して指定するエンコードを

    大文字にすることで実現可能でした。

    document.Declaration = New XDeclaration("1.0", "Shift_JIS", Nothing)
    

    ・・・

    Using writerWriter As New StreamWriter("C:\data.xml", False, System.Text.Encoding.GetEncoding("shift_jis"))
      writerWriter.WriteLine(document.Declaration)
      writerWriter.WriteLine(document.ToString())
    End Using
    

    2010年12月22日 3:13
  • なかむらさんとhonefaiさんに教わったコードで望みどおりのXMLをファイルに出力する事が出来ました。

    皆様、ご回答の程ありがとうございました。

    2010年12月22日 8:36