Avatar billede 123maka Nybegynder
26. december 2008 - 07:56 Der er 9 kommentarer og
1 løsning

XPath i .net

Jeg har et addon til Firefox som hedder Xpather. Her kan jeg finde mig frem til "United States" i toppen på http://www.microsoft.com/en/us/default.aspx .

Dens xpath er: /html/body[@class='ltr']/form[@id='aspnetForm']/div[@class='h15-bottom' and position()=2]/div[@class='h15-header' and position()=1]/div[@class='h15-header-inner' and @id='hpToolbar']/strong[@class='h15-country']

Hvordan bruger jeg det i min kode? Jeg har prøvet:
SgmlReader r = new SgmlReader();
            r.Href = "http://www.microsoft.com/en/us/default.aspx";
            XmlDocument doc = new XmlDocument();
            doc.Load(r);
            XmlNode firstNavItemNode = doc.SelectSingleNode("/html/body[@class='ltr']/form[@id='aspnetForm']/div[@class='h15-bottom' and position()=2]/div[@class='h15-header' and position()=1]/div[@class='h15-header-inner' and @id='hpToolbar']/strong[@class='h15-country']");   
            Debug.Assert(firstNavItemNode.InnerText == "United States");

Jeg bruger SGMLReader fra http://wiki.developer.mindtouch.com/SgmlReader
Avatar billede arne_v Ekspert
26. december 2008 - 22:58 #1
Der er namespace i den XML !

Følgende virker hos mig:

using System;
using System.Xml;

using Sgml;

namespace E
{
    public class Program
    {
        public static void Main(string[] args)
        {
            SgmlReader r = new SgmlReader();
            r.Href = "http://www.microsoft.com/en/us/default.aspx";
            XmlDocument doc = new XmlDocument();
            doc.Load(r);
            XmlNamespaceManager nsm = new XmlNamespaceManager(doc.NameTable);
            nsm.AddNamespace("defns", "http://www.w3.org/1999/xhtml");
            XmlNode n = doc.SelectSingleNode("/defns:html/defns:body[@class='ltr']/defns:form[@id='aspnetForm']/defns:div[@class='h15-bottom' and position()=2]/defns:div[@class='h15-header' and position()=1]/defns:div[@class='h15-header-inner' and @id='hpToolbar']/defns:strong[@class='h15-country']/text()", nsm);
            Console.WriteLine(n.Value);
            Console.ReadKey(true);
        }
    }
}
Avatar billede 123maka Nybegynder
28. december 2008 - 07:36 #2
Ja det virker. Hvad var det for et trick du gjorde med /text() ?

Men nu var microsoft bare et eksempel. Synes stadig den fejler andre steder. Jeg er begyndt at bruge HtmlAgilityPack, den kan fås på http://www.codeplex.com/htmlagilitypack

Hvis vi prøver at hente fra http://speed.travian.dk/ og vil have fat i noget på den. Så prøver jeg at få noget fra den side. Fx. "Navn:" i login feltet.

using HtmlAgilityPack;
using System.Net;

namespace app
{
    class Program
    {
        // Main begins program execution
        public static void Main()
        {
            CookieContainer travCookie = new CookieContainer();
            HtmlDocument doc = new HtmlDocument();

            doc.LoadHtml(webutils.getHTML("http://speed.travian.dk/", "", travCookie));
            HtmlNode theRoot = doc.DocumentNode;
            System.Console.WriteLine(theRoot.SelectSingleNode("/html/body/div[@id='lmidall']/div[@id='lmidlc']/div[@id='lmid1']/div[@id='lmid3']/form/table[@class='p1']/tbody/tr/td/table/tbody/tr[1]/td/label").InnerHtml);
        }
    }
}

Jeg har tjekket sourcekoden igennem på siden om der skulle findes et namespace. Men jeg tror ikke det er det som er tilfældet.
Avatar billede arne_v Ekspert
28. december 2008 - 16:00 #3
/text() erstatter den meget grimme .InnerText()

den virkelige ændring er brug af namespace
Avatar billede 123maka Nybegynder
28. december 2008 - 21:44 #4
Ja ok.. Men har du et fix til mit næste problem? Din kode fejler vist også i det tilfælde med
/html/body/div[@id='lmidall']/div[@id='lmidlc']/div[@id='lmid1']/div[@id='lmid3']/form/table[@class='p1']/tbody/tr/td/table/tbody/tr[1]/td/label
Avatar billede arne_v Ekspert
28. december 2008 - 23:57 #5
Ja.

Der er ikke noget tbody element i den resulterende XML.

using System;
using System.Xml;

using Sgml;

namespace E
{
    public class Program
    {
        public static void Main(string[] args)
        {
            SgmlReader r = new SgmlReader();
            r.Href = "http://speed.travian.dk/ ";
            XmlDocument doc = new XmlDocument();
            doc.Load(r);
            doc.Save(@"C:\z.z");
            XmlNode n = doc.SelectSingleNode("/html/body/div[@id='lmidall']/div[@id='lmidlc']/div[@id='lmid1']/div[@id='lmid3']/form/table[@class='p1']/tr/td/table/tr[1]/td/label/text()");
            Console.WriteLine(n.Value);
            Console.ReadKey(true);
        }
    }
}

udskriver:

Navn:
Avatar billede arne_v Ekspert
29. december 2008 - 00:19 #6
HTML Agility Pack har et problem med form tag.

Men følgende virker:

using System;
using System.Net;

using HtmlAgilityPack;

namespace E
{
    public class Program
    {
        public static void Main(string[] args)
        {
            WebClient wc = new WebClient();
            string html = wc.DownloadString("http://speed.travian.dk/");
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(html);
            HtmlNode root = doc.DocumentNode;
            HtmlNode n = root.SelectSingleNode("/html/body/div[@id='lmidall']/div[@id='lmidlc']/div[@id='lmid1']/div[@id='lmid3']/*/table[@class='p1']/tr/td/table/tr[1]/td/label");
            Console.WriteLine(n.InnerHtml);
            Console.ReadKey(true);
        }
    }
}
Avatar billede 123maka Nybegynder
29. december 2008 - 05:54 #7
Fedt nok. Tak for hjælpen.

Hvordan ser jeg den resulterende XML? Bare så jeg selv kan finde ud af at scanne den igennem selv og finde XPath og ikke skal spørge om hjælp hver gang.
Avatar billede arne_v Ekspert
29. december 2008 - 14:51 #8
Hvis du kigger på min SGML kode, så er der faktisk stadig en lille debug linie !

doc.Save(@"C:\z.z");

gemmer XML'en ...
Avatar billede arne_v Ekspert
29. december 2008 - 14:51 #9
og et svar
Avatar billede 123maka Nybegynder
29. december 2008 - 21:44 #10
Endnu en gang rigtig mange tak :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester