なひです。

> From: Masatoshi SEKI
> Sent: Friday, January 11, 2002 9:02 AM

> i> | ここだけ読むと、Structでもよい?

誰もデバガに突っ込んでくれない。。。

> i> ちなみにXMLも同様にできるのか気になってます。
> i> 
> i> a.xml
> i> ------------------------
> i> <file>
> i>  <name>sample.txt</name>
> i>  <path>/home/morikawa/tmp</path>
> i> </file>
> i> ------------------------
> i> 
> i> file = ?????.parse 'a.xml'
> i> puts file.name
> i> puts file.path
> i> 
> i> みたいな。
> 
> 同じ名前の要素が複数あるときは工夫が要りそうですね。

SOAP Encodingという、オブジェクトのXMLエンコーディングフォーマットが
あります。そこでも同名の要素複数を許しています。

SOAP4Rというモジュールを使います。

begin
  require 'pp'
  def p( obj )
    PP.pp( obj )
  end
rescue LoadError
  p "pp is a must."
end

str = <<EOS
<file1>
  <name>sample.txt</name>
  <name>sample.txt</name>
  <path>/home/morikawa/tmp</path>
</file1>
EOS

require 'soap/processor'
opt = {
  'defaultEncodingStyle' =>
    SOAP::EncodingStyleHandlerASPDotNet::Namespace
}
parser = SOAP::Processor.loadParser( opt )

soapObj = parser.parse( str )
# p soapObj

require 'soap/rpcUtils'
obj = SOAP::RPCUtils.soap2obj( soapObj )

p obj # => #<SOAP::RPCUtils::Object:0x16fc8c
      #     @name=["sample.txt", "sample.txt"],
      #     @path="/home/morikawa/tmp">

fileがfile1になっているのは、現行のSOAP4Rだと
Fileオブジェクトに戻してしまうためです。バグだ。。。

ちなみにSOAP Encodingを使って
File1 = Struct.new( :name, :path )
をEncodingすると、正しくはこんな感じ。

$ ruby -rsoap/marshal -e '
File1 = Struct.new( :name, :path )
puts SOAP::Marshal.marshal(
  File1.new( "sample.txt", "/home/morikawa/tmp" )
)'

<?xml version="1.0" ?>
<env:Envelope
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <env:Body>
    <File1
        xsi:type="n2:File1"
        env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:n1="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:n2="http://www.ruby-lang.org/xmlns/ruby/type/custom">
      <name xsi:type="xsd:string">sample.txt</name>
      <path xsi:type="xsd:string">/home/morikawa/tmp</path>
    </File1>
  </env:Body>
</env:Envelope>

# インデントは手動でやってます。