Forums

XName in System.Xml.Linq

General discussion about Cobra. Releases and general news will also be posted here.
Feel free to ask questions or just say "Hello".

XName in System.Xml.Linq

Postby terenced » Mon Feb 14, 2011 1:12 pm

@ref 'System.Xml'

use System.Xml.Linq

class Program
def main
showname = 'Californication'
xml = XDocument.load('http://www.tvrage.com/feeds/episode_list.php?show=[showname]')
print xml.element('show')


I get the following error running this code
TVRage.cobra(9): error: Argument 1 of method "element" expects type XName?, but the call is supplying type String.
Compilation failed - 1 error, 0 warnings
Not running due to errors above.


However, you cannot create an Xname, and in C#, you simply supply a string to the method 'Element', like so
Code: Select all
using System;
using System.Xml.Linq;

namespace TVRage
{
    class Program
    {
        static void Main(string[] args)
        {

            const string showName = "Californication";
            var xml = XDocument.Load("http://www.tvrage.com/feeds/episode_list.php?show=" + showName).Element("Show");

           Console.WriteLine(xml);
        }
    }
}


Any ideas?
terenced
 
Posts: 15
Location: Montreal, Quebec, Canada

Re: XName in System.Xml.Linq

Postby Charles » Mon Feb 14, 2011 2:29 pm

The .element method takes an XName:
http://msdn.microsoft.com/en-us/library/system.xml.linq.xcontainer.element.aspx

But then an examination of an XName shows that the only way you can create one is through the implicit cast operator:
http://msdn.microsoft.com/en-us/library/system.xml.linq.xname.aspx

Ug! This is the first time I've seen Microsoft rely on C#-specific features in one of their own libraries. Usually they are good about following the Common Type System (CTS) and related specs so that all languages can use them.

I also don't see why they didn't just overload the .element method to take a string, which is a common technique.

Until Cobra picks up the implicit cast operators, I do have a work around:

@ref 'System.Xml'

use System.Xml
use System.Xml.Linq


extend XDocument

def element(name as String) as XElement
return sharp'_lh_this.Element(name)'


class Program

def main
showname = 'Californication'
xml = XDocument.load('http://www.tvrage.com/feeds/episode_list.php?show=[showname]')
print xml.element('show')


Compiled with:
Code: Select all
cobra -c -native-compiler:C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe xml.cobra


Let me know how it goes. Maybe we can cook up a more extensive example and post it in the wiki or the samples section.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: XName in System.Xml.Linq

Postby terenced » Mon Feb 14, 2011 4:36 pm

Oh cool!
I also tired
@ref 'System.Xml'

use System.Xml.Linq

class Program
def main
showname = 'Californication'
xml = XDocument.load('http://www.tvrage.com/feeds/episode_list.php?show=[showname]')
print xml.element('show' to XName)

and it also worked.

However, I tired to be a bit more sneaky and did the following
@ref 'System.Xml'

use System.Xml
use System.Xml.Linq


extend XContainer

def element(name as String) as XElement?
return .element(name to XName)


class Program

def main
showname = 'Californication'
xml = XDocument.load('http://www.tvrage.com/feeds/episode_list.php?show=[showname]')
print xml.element('Show').element('name').value

I used XContainer instead of XDocument, this way XElement would also have the extension method. The casting seems a bit simpler than inbedding C# code ;)
I am working on a little app that will make use of my Linq-fu, so we can definitely get few examples for the wiki.
I also created a mini bundle for TextMate, nothing fancy. Would you like it as well?
terenced
 
Posts: 15
Location: Montreal, Quebec, Canada

Re: XName in System.Xml.Linq

Postby terenced » Mon Feb 14, 2011 5:27 pm

Strange, if I add another extension, I get some funny errors
@ref 'System.Xml'

use System.Xml
use System.Xml.Linq


extend XContainer

def element(name as String) as XElement?
return .element(name to XName)

def attribute(name as String) as XAttribute?
return .attribute(name to XName)


class Program

def main
showname = 'Californication'
xml = XDocument.load('http://www.tvrage.com/feeds/episode_list.php?show=[showname]').element('Show')
print xml.element('name').value
for seasons in xml.element("Episodelist").elements
if seasons.attribute('no') <> nil
print '\tSeasons: [int.parse(seasons.attribute("no").value)]'


I get the following errors:
xml.cobra(13): error: Argument 1 of method "attribute" expects type String?, but the call is supplying type XName.
xml.cobra(23): error: Argument 1 of method "attribute" expects type XName?, but the call is supplying type String.
xml.cobra(24): error: Argument 1 of method "attribute" expects type XName?, but the call is supplying type String.
Compilation failed - 3 errors, 0 warnings
Not running due to errors above.

Now, I did get something similar when I created the 1st extension for element, but it went away when I upgraded Mono.
terenced
 
Posts: 15
Location: Montreal, Quebec, Canada

Re: XName in System.Xml.Linq

Postby Charles » Mon Feb 14, 2011 9:07 pm

In the MSDN docs, I don't see an .attribute on XContainer. So then the compiler thinks you're calling the only .attribute it knows about--the one you're declaring. And that makes for a type error since it expects a String, not an XName.

I don't see it on XDocument either, but I do see it on XElement. So I added an "extend XElement" before "def attribute" and now the code compiles.

With all these XClasses, I'm expecting to see XMen. :-)
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: XName in System.Xml.Linq

Postby Charles » Mon Feb 14, 2011 10:00 pm

And yes, please post your TextMate bundle in a new topic called TextMate. Thanks.
Charles
 
Posts: 2515
Location: Los Angeles, CA


Return to Discussion

Who is online

Users browsing this forum: No registered users and 59 guests