C# - XML állományok transzformálása

forráskód letöltése
Cikkünkben bemutatjuk a System.Xml.Xsl névtér XslTransform osztályát, melynek segítségével elérhetjük, hogy egy XML állományban megtalálható információt – amely lehet például egy SQL adattábla lekérdezésének eredményhalmaza – megjelenítsünk web oldalunkon úgy, hogy felhasználunk egy XSLT állományt a megjelenítés stílusának leírására, valamint az említett osztály metódusait.
Mellékelt példa megnyitása előtt szükséges egy TransformXml nevű virtuális könyvtár létrehozása, mely a példa könyvtárára mutat. Ehhez nyissa meg a mellékelt mappa Tulajdonság ablakát és itt a Webmegosztás lapon engedélyezze a mappa megosztását olvasási és parancsfájlok futtatási jogával.
Az XMLT állományok, és egyáltalán a szabvány célja, hogy az XML állományokban megtalálható adatokat valamilyen más formába alakítsuk (transzformáljuk), mely formájában és struktúrájában is eltér az XML állományétól. Ilyen forma lehet például a HTML formátum, mellyel adatainkat már megjeleníthetjük Web lapjainkon.
A szabályrendszer a W3C szabványügyi konzorcium XSL Transformations (XSLT) Version 1.0 szabványán nyugszik, mely a www.w3.org/TR/xslt helyen található.
A .NET Framework a System.Xml.Xsl névtérben található XslTransform osztályt nyújtja a művelet megvalósításához. Ez egy XSLT processzor, mely műveleteit a szabvány alapján végzi el.
Az XslTransform osztályban két metódust találunk, lássuk ezeket sorban. Mivel mindkét metódusnak több változata van, csak azokkal foglalkozunk, melyeket a példa alkalmazásban is felhasználtunk.
Load
Osztály: XslTransform
public void Load(
string url
);
Betölti az URL-el azonosított XSLT állományt. Amennyiben az elérhető és betöltött .xslt állomány nem megfelelő, egy Exception kivétel generálódik.
Paraméterek
string url
Az állomány URL-je karakteres formában.
Transform
Osztály: XslTransform
public void Transform(
XPathNavigator input,
XsltArgumentList args,
TextWriter output
);
Az első paraméterben megadott XML állományon elvégzi a transzformációt, majd az eredményt betölti egy TextWriter osztályból származó osztályú objektumba.
Paraméterek
XPathNavigator input
A bemeneti XML állományt tartalmazó objektum. A feladatban az IXPathNavigable interfészt implementáló XpathDocument osztályt használjuk, mely alkalmas arra, hogy egy gyors működésű cache tárat biztosítson az XML állománynak abban az esetben, amikor XSLT transzformációra kerül sor. Létrehozásakor konstruktorában megadjuk az XML állomány URL-jét egy karakterláncban. Segítségével az XPath modellt alkalmazhatjuk az XML állomány olvasásához, az egyes csomópontokban megtalálható információkra történő pozícionálásával.
XsltArgumentList args
Értéke példánkban null. Az adott XSLT állományhoz adott attribútumok listáját tartalmazza.
TextWriter output
Egy TextWriter osztályból származó osztály objektuma (példánkban ez egy StringWriter objektum), mely tartalmazza az eredmény karaktersorozatot.
A feladat megoldása érdekében készítettünk egy függvényt TransXml néven, mely két paramétert vár, ezekben adjuk meg egy-egy string-ben az XML, illetve XSLT állományok helyét.
A products.xml állomány egy adatbázis-lekérdezés eredményét tartalmazza, melyet a Northwind adatbázis Products táblájából készítettünk. Az adathalmaz a tábla ProductID, ProductName és UnitPrice oszlopinak értékeit tartalmazza, és csak azok a rekordok kerültek bele, melyeknek ProductID oszlopában 30-nál kisebb érték szerepel.
Az XSLT állományban egy xsl:template szegmensben helyezzük el a leíró adatokat, először a megjelenítés formáját adjuk meg, mely egy HTML tábla:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <TABLE cellpadding="5">
      <TR>
        <TD class="f8b">Termékazonosító</TD>
        <TD class="f8b">Terméknév</TD>
        <TD class="f8b">Egységár</TD>
      </TR>
Majd megadjuk a feldolgozás logikáját, mely szerint a NewDataSet csomópontban elhelyezett Products csomópont elemeit 30-szor kiolvassuk, hiszen ennyi Products csomópont van. Minden egyes Products csomópontban beolvassuk a három oszlop értékét:
         <xsl:for-each select="NewDataSet/Products">
         <TR>
           <TD>
             <xsl:value-of select="ProductID" />
           </TD>
           <TD>
             <xsl:value-of select="ProductName" />
           </TD>
           <TD>
             <xsl:value-of select="UnitPrice" />
           </TD>
         </TR>
       </xsl:for-each>
     </TABLE>
   </xsl:template>
 </xsl:stylesheet>
A TransXml metódus a következő: először példányosítjuk a StringWriter osztályt, majd létrehozunk egy XmlReader objektumot az XML állományhoz, mint adatfolyamhoz a speciális állományformátum miatt.
public string TransXML(string xmlUrl, string xslUrl)
{
  string state = "";
  StringWriter sWriter = new StringWriter();
  try
  {
    XmlTextReader xmlReader =  new XmlTextReader(xmlUrl);
Létrehozzuk az XslTransform osztályt, és betöltjük az XSLT állományt:
    XslTransform xsltTrans = new XslTransform();
    xsltTrans.Load(xslUrl);
A transzformáció eredményét egy string-be írjuk, hiba esetén egy hibaüzenetet teszünk ugyanebbe a változóba. Ez lesz metódusunk visszatérési értéke.
    XPathDocument xmlXPath = new XPathDocument(xmlReader);
    xsltTrans.Transform(xmlXPath,null,sWriter);
    state = sWriter.ToString();
  }
  catch (System.Exception e)
  {
    state = "<font color=red size=4pt><br>Hiba történt az állományok olvasásakor, például mert az állományok nem elérhetőek a megadott helyen!</br></font>";
  }
  return state;
}
A Render metódussal kiírjuk az oldal tartalmát a HTML adatfolyamba, mely böngészőnkben megjelenik:
protected override void Render(HtmlTextWriter writer)
{
  string sHelp = TransXML("http://localhost//TransformXml//products.xml","http://localhost//TransformXml//products.xslt");
  writer.Write(sHelp);
}