Pokazywanie postów oznaczonych etykietą xml. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą xml. Pokaż wszystkie posty

sobota, 21 czerwca 2014

[HTML|JS|CSS] HTML: Transformaty XSLT

Transformaty XSLT to popularny mechanizm przetwarzania plików XML. Wynikiem może być HTML, inny XML lub dowolny plik tekstowy. Arkusz XSL zawiera zestaw reguł określających, które fragmenty wejściowego XML-a transformować do wyniku i w jakie dodatkowe informacje je uzupełnić. Ścieżki podajemy za pomocą XPATH-a.

Najprostszy przykład użycia XSLT to hostowanie pliku XML. Nie chcemy wyświetlać go bezpośrednio użytkownikowi, dlatego decydujemy się na prostą transformację do HTML-a. W tym celu w drugiej linii XML-a umieszczamy link do transformaty.

<?xml version="1.0"?>
<?xml-stylesheet href="mytransform.xsl" type="text/xsl"?>

Szablon powinien składać się z tzw. template'ów czyli fragmentów kodu dopasowanych do elementów XML-a, które mają one przetwarzać. Przykładowo template, który zastosuje się do roota XML-a:

<xsl:template match="/">
  <html>
  <body>
  <h2>My books</h2>  
  <xsl:apply-templates/>  
  </body>
  </html>
</xsl:template>

Instrukcja apply-templates spowoduje wykonanie się pozostałych szablonów pasujących do elementów wewnątrz root-a. Wewnątrz tego pliku mamy jeszcze zdefiniowany szablon pasujący do elementów typu catalog.

<xsl:template match="catalog">
  <table>
   <thead>
    <tr>
     <th>Title</th>
     <th>Author</th>
     <th>Price category</th>
    </tr>
   </thead>
    <xsl:for-each select="book">
     <xsl:if test="./attribute::id != $hiddenId">
     <tr>
      <td>
       <xsl:value-of select="title" />
      </td>
      <td>
       <xsl:value-of select="author" />
      </td>
      <td>
       <xsl:choose>
        <xsl:when test="price &gt; 10 and price &lt; 50">
         cheap
        </xsl:when>
        <xsl:when test="price &gt; 50 and price &lt; 100">
         medium
        </xsl:when>
        <xsl:otherwise>expensive</xsl:otherwise>
       </xsl:choose>
      </td>
     </tr>
     </xsl:if>
    </xsl:for-each>
  </table>
</xsl:template>

Szablon taki buduje tabelę przechodząc po wszystkich elementach typu book za pomocą instrukcji for-each. Mamy także do dyspozycji dwie instrukcje sterujące: prostszą xsl-if (sprawdza tylko, czy dany fragment kodu ma się wykonać) oraz bardziej złożoną xsl-choose (z uwzględnieniem wielu warunków, odpowiada switchowi z języka C). Zapis ./ oznacza odwołanie do obecnie przetwarzanego elementu, natomiast poprzez /attribute::nazwa możemy wyciągać wartości z atrybutów. XSLT pozwala także na definiowanie własnych zmiennych, do których odwołujemy się przez $zmienna, np.

<xsl:variable name="hiddenId" select="'bk101'"/>

wtorek, 6 sierpnia 2013

[C#|Visual Studio] LINQ to XML

LINQ to XML, jak nazwa wskazuje umożliwia wykonywanie zapytań LINQ na plikach XML wczytywanych do pamięci za pomocą klasy XDocument. Przykładowy plik XML:

<?xml version="1.0" encoding="utf-8" ?>
<peaks>
  <peak>
    <name>Rysy</name>
    <height unit="mnpm">2499</height>
  </peak>
  <peak>
    <name>Swinica</name>
    <height unit="mnpm">2301</height>
  </peak>
  <peak>
    <name>Kasprowy Wierch</name>
    <height unit="mnpm">1987</height>
  </peak>
  <peak>
    <name>Szpiglasowy Wierch</name>
    <height unit="mnpm">2172</height>
  </peak>
</peaks> 

Plik taki możemy odpytywać przy użyciu zapytań LINQ, np.:

//Queries
XDocument xmlDocument = XDocument.Load("tatra.xml");

var twoThousand = from peak in xmlDocument.Root.Elements("peak")
                  let height = int.Parse(peak.Element("height").Value)
                  where height > 2000
                  select peak.Element("name").Value;

foreach (var peak in twoThousand)
    Console.WriteLine(peak);

LINQ to XML to nie tylko odczyt, ale także wygodna możliwość modyfikacji. Aby dodać nowy szczyt wystarczy skorzystać z klasy XElement, dla której jednym z argumentów jest params umożliwiający budowanie drzewa. Przykład poniżej:

//Modifying
var peaks = xmlDocument.Root;
peaks.Add(new XElement("peak", new XElement("name", "Zawrat"),
                       new XElement("height", new XAttribute("unit", "mnpm"), 2159)));

xmlDocument.Save("tatra2.xml");


Również usuwanie elementów jest bardzo proste.

//Deleting
var highest =
    peaks.Elements("peak").OrderByDescending(x => int.Parse(x.Element("height").Value))
    .FirstOrDefault();
highest.Remove();

xmlDocument.Save("tatra3.xml");

niedziela, 26 sierpnia 2012

[WPF] HierarchicalDataTemplate

Podczas stosowanie data bindingu, dane mogą być nam dostarczone w różnej postaci. Mogą to być pojedyncze wartości, kolekcje przeróżnych typów, ale często zdarzy się, że są dostarczone w postaci hierarchicznej. WPF ułatwia bindowanie się do plików XML, za pomocą specjalnych mechanizmów.Pierwszy z nich do XmlDataProvider zapewniający binding i notyfikację każdej zmiany, jaka zajdzie po obu stronach. Kolejnym jest HierarchicalDataTemplate, który umożliwia binding do hierarchicznej struktury.

Mając przykładowe dane w pliku Countries.xml:


<?xml version="1.0" encoding="utf-8" ?>
<Countries>
  <Country Name="Poland">
    <CapitalCity>Warsaw</CapitalCity>
    <Voivodeships>
      <Voivodeship Name="Masovian">
        <Cities>
          <City>Plock</City>
          <City>Radom</City>
          <City>Warsaw</City>
        </Cities>
      </Voivodeship>
      <Voivodeship Name="Lesser Poland">
        <Cities>
          <City>Cracow</City>
          <City>Tarnow</City>
        </Cities>
      </Voivodeship>
      <Voivodeship Name="Greater Poland">
        <Cities>
          <City>Kalisz</City>
          <City>Poznan</City>
        </Cities>
      </Voivodeship>      
    </Voivodeships>  
</Country>
</Countries>

Możemy do resourców dodać XmlProvider z ścieżką do pliku.

<XmlDataProvider Source="Countries.xml" XPath="Countries" x:Key="MyProvider" />

A następnie, również w resourcach dodać hierarchiczny szablon danych.


<HierarchicalDataTemplate DataType="Countries" ItemsSource="{Binding XPath=*}">
    <TextBlock Text="Countries" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="Country" ItemsSource="{Binding XPath=*}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding XPath=@Name}" />
        <TextBlock Text=", Capital City : " />                
        <TextBlock Text="{Binding XPath=CapitalCity}" />
    </StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="Voivodeships" ItemsSource="{Binding XPath=*}">
    <TextBlock Text="Voivodeships :" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="Voivodeship" ItemsSource="{Binding XPath=*}">
    <TextBlock Text="{Binding XPath=@Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="Cities" ItemsSource="{Binding XPath=*}">
    <TextBlock Text="Cities" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="City" >
    <TextBlock Text="{Binding XPath=.}" />
</HierarchicalDataTemplate>

Ostatecznie możemy zbindować dane z providera do kontrolki TreeView.


 <TreeView ItemsSource="{Binding Source={StaticResource ResourceKey=MyProvider}, XPath=.}"  />

I tym sposobem możemy przeglądać drzewo z naszymi danymi zapisanymi w takiej hierarchii, jak w pliku XML