[MacRuby-devel] UTF8 Strings [resolved]

s.ross cwdinfo at gmail.com
Sun Dec 6 19:17:13 PST 2009


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 <cwdinfo at gmail.com> 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 <vincent.isambart at gmail.com>
>> 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
>>> MacRuby-devel at lists.macosforge.org
>>> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
>> 
>> _______________________________________________
>> MacRuby-devel mailing list
>> MacRuby-devel at lists.macosforge.org
>> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
>> 
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel



More information about the MacRuby-devel mailing list