This was a combination of what Vincent said [read the documentation... sorry 
about my snippy reply earlier] and what is apparently my misreading of the "How 
Does MacRuby Work?" Wiki page. Brian, your pointer led me down the path toward 
understanding the underlying mapping of types that caused the confusion in my 
code. I'll explain so if anyone else runs into this, they might find it useful.

In http://www.macruby.org/trac/wiki/HowDoesMacRubyWork, (How Does MacRuby 
Work?) the following statement is made:

------
Because NSString was not designed to handle bytestrings, MacRuby will 
automatically (and silently) create an NSData object when necessary, attach it 
to the string object, and proxy the methods to its content. This will typically 
be used when you read binary data from a file or a network socket.
------

I understand the difference between an NSString and an NSMutableString, but my 
reading of the above is that you can use an NSString (or, in my reading, 
NSMutableString) anywhere an NSData is required and kinda vice-versa. Evidently 
that's not the case. So explicitly converting to NSData using the proper 
encoding is the cure that makes initWithData:data options:options error:error 
work. The caveat in the above quote about where the silent creation of an 
NSData object occurs was not sufficient to set off alarm bells when I read it.

So now that I knew that I could create an NSXMLDocument from an NSData, I 
wanted to dig a bit further and find out why I couldn't make one from an 
NSString. I learned that there are at least three different initWithXMLString 
methods in Cocoa. Depending on the class, the selector is formed differently. 
So I used the Xcode help to search for initWithXMLString and found 
(id)initWithXMLString:(NSString *)string. Made sense, so I didn't look further. 
Again, Vincent, my apologies for not having done that. This method belongs to 
NSXMLDTDNode.

So the working code, using the information all of you have so patiently given 
me is:

# shebang so I can just Cmd+R inside Textmate
#!/path/to/macruby

framework "Cocoa"

xmlDoc = NSXMLDocument.alloc.initWithXMLString(s, options:NSXMLDocumentTidyXML, 
error:error)
NSLog("Created XML Document %@", xmlDoc)
NSLog("Root element is %@", xmlDoc.rootElement)
NSLog("Error is %@", error.class)

nodes = xmlDoc.nodesForXPath("//person", error:error)

nodes.each do |node|
  NSLog("Node is %@", node)
  name    = node.nodesForXPath("./name", error:error)[0] || 'n/a'
  address = node.nodesForXPath("./address", error:error)[0] || 'n/a'
  NSLog("Name: #{name.stringValue}")
  NSLog("Address: #{address.stringValue}")
end

This does a whole bunch of logging, but illustrates what I haven't seen clearly 
in all my searching through Google and reading the example code. That, as 
Laurent says, Cocoa has a wonderful XML document class that will do what I was 
using REXML to do.

Thanks...

Steve


On Dec 6, 2009, at 6:18 PM, Brian Chapados wrote:

> On Sun, Dec 6, 2009 at 3:02 PM, S. Ross <[email protected]> wrote:
>> Yes, well I did read the documentation but thanks for the suggestion. I just
>> mistyped in my email. I'm also specifying the Cocoa framework.
>> 
>> None of that seems to explain why initWithData:error returns null.
> 
> In the original code you showed, you were passing an NSMutableString
> object to initWithData:options:error:. If you want to use
> initWithData:options:error: you need to convert your string to a data
> object:
> 
> xml_data = s.dataUsingEncoding(NSUTF8StringEncoding)
> 
> Or, if the source data is coming from some other source, you might be
> able to create an NSData object directly.



>> I'll give it another whirl.
>> 
>> Hunted and pecked from my iPhone
>> 
>> On Dec 6, 2009, at 2:27 PM, Vincent Isambart <[email protected]>
>> wrote:
>> 
>>>> * initWithString is simply unrecognized as a method
>>> 
>>> Please look at the documentation first. It's initWithXMLString not
>>> initWithString
>>>> 
>>>> * NSXMLDocumentTidyXML constant is not defined so I just transcribed the
>>>> equivalent bitshift
>>> 
>>> If you do framework 'Cocoa', NSXMLDocumentTidyXML is properly defined...
>>>> 
>>>> * The resultant XML document is null
>>> 
>>> It works fine if you use initWithXMLString:options:error:
>>> _______________________________________________
>>> MacRuby-devel mailing list
>>> [email protected]
>>> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
>> 
>> _______________________________________________
>> MacRuby-devel mailing list
>> [email protected]
>> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
>> 
> _______________________________________________
> MacRuby-devel mailing list
> [email protected]
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

_______________________________________________
MacRuby-devel mailing list
[email protected]
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

Reply via email to