XML
XSLT
PDF
Børre Stenseth
Moduler>XML>XML og Vin

Vin og XML

Hva
Bruk av XML, XSLT og WebBrowser

Vi skal ta for oss en XML-fil med vinbeskrivelser og lage en applikasjon som lar oss søke etter (grupper av) viner i denne fila. Vi skal begrense utvalget til å gjelde produksjonsland og vintype. Vi skal dessuten lage en enkel PDF-versjon av utvalget.

Image1

Råmaterialet er beskrevet i modulen Noen datasett, og er en XML-fil som som ser slik ut:


<?xml version="1.0" encoding="UTF-8"?>
<wines>
    <wine>
        <type>sparkling</type>
        <name>Gosset Grande Réserve Brut</name>
        <catalog>32299</catalog>
        <country>Frankrike</country>
        <volume>75</volume>
        <price>259.00</price>
        <dice>5</dice>
        <description>Syrefrisk og harmonisk smak med god fylde.</description>
    </wine>
    ...
</wines>

Altså en enkel liste med <wine>-elementer uten noen spesiell ordning. Vi kan lage utvalg fra denne fila på mange forskjellige måter. Det er i hvert fall tre angrepsvinkler som peker seg ut:

  • Vi kan etablere et DOM-tre i hukommelsen og skrive vår egen rutine som vandrer i treet og plukker ut det vi vil ha
  • Vi kan etablere et DOM-tre i hukommelsen og skrive vår egen rutine som bruker et XPath uttrykk til å plukke ut det vi er ute etter
  • Vi kan skrive en XSLT-fil som transformerer XML-fila ved å lage et utvalg.

Vi velger den siste løsningen. Fordelen er at vi kan lage en transformasjon som lager HTML-format for oss direkte. Dette ka vi presentere i et browser vindu i applikasjonen. Ulempen er at vi kanskje har litt mindre kontroll dersom vi skal lage kompliserte utvalgskriterier.

Transformasjonen

Siden vi skal la brukeren gjøre ulike typer utvalg, må vi gjøre XSLT-transformasjonen parameterstyrt. Den transformasjonen vi bruker ser slik ut:

_tohtml_param.xslt

PDF

PDF-vesjonen lages ved hjelp av Prince XML [1] . Vi kjører Prince vi en ekstern kommando, slik:

private void buttonPDF_Click(object sender, EventArgs e)
{
    // make pdf from the vines selected
    String sourcePath = webBrowser1.Url.AbsolutePath;
    String stylePath = Path.Combine(Application.StartupPath, 
                                   "data\\report.css");
    String resultPath = Path.Combine(Application.StartupPath, 
                                   "data\\report.pdf");
    Process PP = new Process();
    try
    {
        PP.StartInfo.UseShellExecute = true;
        String args = "{0} -s {1}";
        PP.StartInfo.FileName = PRINCE_PATH;
        PP.StartInfo.Arguments = 
            String.Format(args, sourcePath, stylePath);
        PP.StartInfo.CreateNoWindow = true;
        PP.Start();
    }
    catch (Win32Exception ex)
    {
        if (ex.NativeErrorCode == ERROR_FILE_NOT_FOUND)
            MessageBox.Show(ex.Message + ". Check the path.");
        else if (ex.NativeErrorCode == ERROR_ACCESS_DENIED)
            MessageBox.Show(ex.Message +
                ". You do not have permission to print this file.");
    }
}

Koden i vinduet som drar det hele ser slik ut:

_Form1.cs

Stilsett

Det er to stilsett involvert. Ett som brukes i vinduet:

body{
    color: black;
    font-family:"Verdana","Geneva","Arial","Times",sans-serif;
    font-size:13px;
    text-align:left;
    margin:0px;
    padding:20px;
 }
h1{font-size:24px}
.ingress{font-size:12px}
.wine{margin-top:15px}
.wine-name{font-size:18px;padding-left:50px}
.wine-desc{}
.wine-country{padding-left:50px; font-weight:bold}
.wine-price{font-weight:normal}
.wine-author{font-weight:normal;font-size:10px;color:gray}

I tillegg brukes følgende i forbindelse med Prince transformasjonen:

@page{
    size: 20.995cm  27.31cm;
    margin: 2.0cm 1.25cm 2.0cm 1.5875cm;
    @top-right{
            content: "Viner";
            font-size:18px;
        }
    @bottom-right {
          vertical-align:top;
          content: counter(page);
          font-style: italic;
          font-size:11px;
          border-top-style:solid;
          border-top-width:thin;
        }
    @bottom-left {
          vertical-align:top;
          content:"Demo";
          font-style: italic;
          font-size:11px;
          border-top-style:solid;
          border-top-width:thin;
        }
 }

Det er klart at denne løsningen kunne vært realisert på mange forskjellige måter.

  • Vi kunne bruke databaser
  • Vi kunne la alt materialet ligge på en server
  • Vi kunne faktisk løst problemet direkte i MSIE ved hjelp av Javascript og transformasjoner direkte i nettleseren. Du finner noe materiale om denne muligheten på Scripting mot MSXML
Referanser
  1. Prince XMLPrincewww.princexml.com/14-03-2010
Prosjekt:
https://svn.hiof.no/svn/psource/Csharpspikes/xmlwinepdf
Du finner mer om XSLT i modulen: XSLT på vevstedet: Markup og web.
En webløsning som gjør det samme er beskrevet i modulen: Noen viner
Vedlikehold
B.Stenseth, revidert desember 2006
(Velkommen) Moduler>XML>XML og Vin (Validering)