<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>j2ee.pl - związani z javą &#187; xml</title>
	<atom:link href="http://j2ee.pl/tag/xml/feed/" rel="self" type="application/rss+xml" />
	<link>http://j2ee.pl</link>
	<description>związani z Javą</description>
	<lastBuildDate>Mon, 24 Aug 2009 11:45:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Dodatkowe dwa słowa o Apache XMLBeans i HSSF POI</title>
		<link>http://j2ee.pl/2007/12/17/dodatkowe-dwa-slowa-o-apache-xmlbeans-i-hssf-poi/</link>
		<comments>http://j2ee.pl/2007/12/17/dodatkowe-dwa-slowa-o-apache-xmlbeans-i-hssf-poi/#comments</comments>
		<pubDate>Mon, 17 Dec 2007 09:01:12 +0000</pubDate>
		<dc:creator>Michał Porzożyński</dc:creator>
				<category><![CDATA[Inne biblioteki]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[xpath]]></category>

		<guid isPermaLink="false">http://j2ee.pl/2007/12/17/dodatkowe-dwa-slowa-o-apache-xmlbeans-i-hssf-poi/</guid>
		<description><![CDATA[Na naszym blogu możesz znaleźć dwa artykuły mojego autorstwa o Apache XMLBeans oraz Apache POI. Ostatnio miałem okazję ponownie pracować  z tymi bibliotekami, napotykając przy tym na dwa problemy, których rozwiązanie nie okazało się dla mnie jakoś specjalnie proste (mimo, że być powinno ;)). Dzisiaj będzie o wykorzystaniu wyrażeń XPath w XMLBeans oraz o [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://j2ee.pl/wp-content/uploads/2007/12/apache.png" alt="ASF" align="left" />Na naszym blogu możesz znaleźć dwa artykuły mojego autorstwa o <a href="http://j2ee.pl/2007/10/20/apache-xmlbeans-bindowanie-danych-xml-do-typow-java/">Apache XMLBeans</a> oraz <a href="http://j2ee.pl/2007/06/28/wstep-do-apache-poi-hssf-dostep-do-plikow-ms-excel-w-javie/">Apache POI</a>. Ostatnio miałem okazję ponownie pracować  z tymi bibliotekami, napotykając przy tym na dwa problemy, których rozwiązanie nie okazało się dla mnie jakoś specjalnie proste (mimo, że być powinno ;)). Dzisiaj będzie o wykorzystaniu wyrażeń XPath w XMLBeans oraz o przeliczaniu formuł zaszytych w arkuszach Excel. Tematy trochę jakby nie mają nic ze sobą wspólnego, ale przecież to tylko dodatkowe dwa słowa ;)<br />
<span id="more-110"></span></p>
<h3>XMLBeans i XPath</h3>
<p>XMLBeans posiada fajną funkcjonalność, pozwalająca na użycie języka <a href="http://en.wikipedia.org/wiki/XPath">XPath</a> do wyciągania z obiektu klasy XmlObject (klasy do której &#8220;wparsowany&#8221; jest nasz xml) potrzebnych nam danych.  Z tak zwanego <em>out of the box,</em> nasza biblioteka pozwala na tworzenie jedynie prostych zapytań XPath (np: //book). Jeżeli chcemy wykorzystać trochę bardziej złożoną semantykę (powiedzmy: //book[@title='EJB3 in Action'])  powinniśmy spiąć XMLBeans z biblioteką <a href="http://saxon.sourceforge.net/">Saxon</a> (procesor XSLT i XQuery). Takie spięcie polega jedynie na dodaniu do naszej aplikacji bibliotek saxon.jar, saxon-dom.jar (znajdują się w jednym archiwum ściąganym ze strony saxona) oraz xbean_xpath.jar (dostępnego razem z dystrybucją XMLBeans). Jeśli środowisko jest już przygotowane, wystarczy wywołać na obiekcie XmlObject metodę selectPath podając w jej parametrze wyrażenie XPath. W odpowiedzi powinniśmy dostać tablicę obiektów XmlObject z interesującymi nas danymi.</p>
<pre class="prettyprint">XmlObject[] data = BookDocument.selectPath("//book[@title='EJB3 in Action']");</pre>
<p>W moim przypadku coś poszło jednak nie tak. Mimo, że sprawdziłem poprawność wyrażenia XPath, zmienna <em>data </em>była nullem. Zajęło mi trochę czasu aby problem rozwiązać. Okazuje się że Apache XMLBeans w wersji 2.3.0 współpracuje tylko z bardzo konkretną wersją biblioteki Saxon: wersją 8.8. Ja posiadałem najnowszego Saxon&#8217;a oznaczonego numerem 9.0. W taki oto sposób straciłem 45 minut i przed tą stratą postanowiłem ostrzec Was :)</p>
<h3>Apache HSSF POI i przeliczanie formuł w Excelu</h3>
<p>O problemie przeliczania formuł w arkuszach MS Excel pisałem już wcześniej. Wtedy była to tylko wzmianka o tym, że istnieje specjalna klasa służąca właśnie do tego (<strong>HSSFFormulaEvaluator</strong>) i że nie udało mi się jej użyć ;) Od wersji 3.0.1 klasa ta już jest niedostępna, a problem pozostał. No właśnie&#8230; może przybliżę problem: powiedzmy, że istnieje arkusz Excela, który posiada tylko trzy pola: A1 &#8211; liczba, A2 &#8211; liczba, A3 = A2 &#8211; A1. Z jakiegoś tylko tobie znanego powodu, za pomocą Apache POI chcesz zmienić liczbę w polu A2 na jakąś inną.. lepszą ;) Robisz wszystko co potrzeba, zapisujesz arkusz na dysku, otwierasz go w Excelu i zauważasz, że formuła w polu A3 ciągle pokazuje wyliczenia z poprzednimi wartościami.  Co należy zrobić aby formuła została przeliczona ? Należy zapamiętać formułę w stringu, nadać komórce typ: HSSFCell.CELL_TYPE_FORMULA oraz zapisać ponownie do komórki zapamiętaną wcześniej formułę. Rozwiązanie proste jak budowa cepa, tym bardziej więc dziwi, że działa tak, jakbyśmy tego chcieli ;)</p>
<pre class="prettyprint">String formula = cell.getCellFormula();
cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
cell.setCellFormula(formula);</pre>
<p>To by było na tyle. Obiecuję, że już nie będę Was męczył zagadnieniami związanymi z POI i XMLBeans :)</p>
]]></content:encoded>
			<wfw:commentRss>http://j2ee.pl/2007/12/17/dodatkowe-dwa-slowa-o-apache-xmlbeans-i-hssf-poi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache XMLBeans &#8211; bindowanie danych XML do typów Java</title>
		<link>http://j2ee.pl/2007/10/20/apache-xmlbeans-bindowanie-danych-xml-do-typow-java/</link>
		<comments>http://j2ee.pl/2007/10/20/apache-xmlbeans-bindowanie-danych-xml-do-typow-java/#comments</comments>
		<pubDate>Sat, 20 Oct 2007 14:51:29 +0000</pubDate>
		<dc:creator>Michał Porzożyński</dc:creator>
				<category><![CDATA[Inne biblioteki]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[xml schema]]></category>

		<guid isPermaLink="false">http://j2ee.pl/2007/10/20/apache-xmlbeans-bindowanie-danych-xml-do-typow-java/</guid>
		<description><![CDATA[Java API for XML Parsing (JAXP) jest dobrym i w zasadzie wystarczającym do codziennej pracy narzędziem, służącym do operowania na XMLu. Tak sobie przynajmniej myślałem, dopóki nie poznałem biblioteki Apache XMLBeans :) W tym,  mam nadzieje, dość zwięzłym i krótkim artykule, postaram się przybliżyć Wam  podstawy korzystania z  &#8220;beansów&#8221;.
Podążając za stroną domową [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://xmlbeans.apache.org/index.html" target="_blank"><img src="http://j2ee.pl/wp-content/uploads/2007/10/project-logo.gif" /></a>Java API for XML Parsing (JAXP) jest dobrym i w zasadzie wystarczającym do codziennej pracy narzędziem, służącym do operowania na XMLu. Tak sobie przynajmniej myślałem, dopóki nie poznałem biblioteki <a href="http://xmlbeans.apache.org/index.html" target="_blank">Apache XMLBeans</a> :) W tym,  mam nadzieje, dość zwięzłym i krótkim artykule, postaram się przybliżyć Wam  podstawy korzystania z  &#8220;beansów&#8221;.<span id="more-95"></span></p>
<p>Podążając za stroną domową projektu: XMLBeans to technologia dostępu do XMLa poprzez bindowanie danych do typów Java. Bindowanie to jest możliwe, dzięki kompilacji wygenerowanych, na podstawie XML Schema, klas Javy i utworzeniu z nich, dołączanej do projektu, biblioteki (archiwum .jar). XMLBeans zostało napisane przez pracowników firmy BEA i podarowane społeczności open source w 2003 roku.</p>
<p>Zalety biblioteki przedstawiał będę na przykładzie aplikacji: prymitywna wypożyczalnia bez możliwości wypożyczania. Lub jak kto woli.. katalog książek :) Dane będą przechowywane oczywiście w pliku XML.</p>
<p>Istotnym elementem działania opisywanej biblioteki jest XML Schema. Jest to opracowany przez W3C standard służący do definiowania struktury dokumentu. Jako, że celem tego artykułu nie jest opis XML Schema, odsyłam osoby nie znające tego standardu do tutorialu na stronie <a href="http://www.w3schools.com/schema/default.asp" target="_blank">w3schools.com</a>. Poniżej przedstawiam Schame wykorzystywaną w mojej prostej aplikacji:</p>
<pre class="prettyprint">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xsd.j2ee.pl/library.xsd" xmlns:j2ee="http://xsd.j2ee.pl/library.xsd"&gt;

  &lt;xs:element name="library" type="j2ee:library" /&gt;
  &lt;xs:element name="book" type="j2ee:book" /&gt;

  &lt;xs:complexType name="library"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="book" type="j2ee:book" maxOccurs="unbounded" /&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;

  &lt;xs:complexType name="book"&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element name="author" type="j2ee:author" maxOccurs="unbounded" minOccurs="1" /&gt;
    &lt;/xs:sequence&gt;
    &lt;xs:attribute name="title" type="xs:string" use="required" /&gt;
    &lt;xs:attribute name="publishYear" type="xs:int" use="required" /&gt;
  &lt;/xs:complexType&gt;

  &lt;xs:complexType name="author"&gt;
    &lt;xs:simpleContent&gt;
      &lt;xs:extension base="xs:string"&gt;
        &lt;xs:attribute name="name" type="xs:string" use="required" /&gt;
        &lt;xs:attribute name="surname" type="xs:string" use="required" /&gt;
      &lt;/xs:extension&gt;
    &lt;/xs:simpleContent&gt;
  &lt;/xs:complexType&gt;

&lt;/xs:schema&gt;</pre>
<p>Struktura danych jest bardzo prosta. Główny element naszej wypożyczalni to <em>library</em> i jest on &#8220;zbiornikiem&#8221; dla elementów typu <em>book</em>. A book jak to book.. ma swój tytuł, rok wydania i listę autorów (reprezentowanych przez element <em>author</em>). Autor natomiast ma, jak to w życiu bywa, swoje imię i nazwisko. Przykładowy XML stworzony na podstawie takiej Schemy może wyglądać tak:</p>
<pre class="prettyprint">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;j2ee:library xmlns:j2ee="http://xsd.j2ee.pl/library.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xsd.j2ee.pl/library.xsd library.xsd "&gt;
  &lt;book publishYear="2007" title="EJB3 in Action"&gt;
    &lt;author name="Debu" surname="Panda" /&gt;
    &lt;author name="Reza" surname="Rahman" /&gt;
    &lt;author name="Derek" surname="Lane" /&gt;
  &lt;/book&gt;
&lt;/j2ee:library&gt;</pre>
<p>Mając już gotową Scheme, możemy przystąpić do wygenerowania i skompilowania na jej podstawie, klas Javy. Po tej operacji otrzymamy archiwum JAR, które dołączymy następnie do naszej aplikacji. Do kompilacji służy załączony do biblioteki program o nazwie <strong>scomp.cmd</strong> (bez rozszerzenia .cmd dla linuxa), który znajduje się w katalogu bin. Najważniejsze dwa atrybuty jakie przyjmuje ten program to nazwa pliku XSD w którym znajduje się definicja XML Schema oraz nazwy pliku wynikowego JAR, ze skompilowanymi klasami.</p>
<pre class="prettyprint">&gt;scomp.cmd -out library.jar library.xsd</pre>
<p>Jeżeli JDK zainstalowane jest w katalogu <em>Program Files</em> (nazwa katalogu ze spacją) program scomp.cmd wykrztusi z siebie taki oto wyjątek:</p>
<pre class="prettyprint">java.io.IOException: Cannot run program "c:\Program": CreateProcess error=2, The system cannot find the file specifiedjava.io.IOException: CreateProcess error=2, The system cannot find the file specifiedjava.io.IOException: Cannot run program "c:\Program": CreateProcess error=2, The system cannot find the file specifiedat java.lang.ProcessBuilder.start(Unknown Source)at java.lang.Runtime.exec(Unknown Source)at java.lang.Runtime.exec(Unknown Source)
  at org.apache.xmlbeans.impl.tool.CodeGenUtil.externalCompile(CodeGenUtil.java:231)
  at org.apache.xmlbeans.impl.tool.SchemaCompiler.compile(SchemaCompiler.java:1154)
  at org.apache.xmlbeans.impl.tool.SchemaCompiler.main(SchemaCompiler.java:373)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
  at java.lang.ProcessImpl.create(Native Method)
  at java.lang.ProcessImpl.&lt;init&gt;(Unknown Source)
  at java.lang.ProcessImpl.start(Unknown Source)
  ... 6 more</pre>
<p>Aby pozbyć się tego niezbyt przyjemnego problemu dodajemy do wywołania programu scomp.cmd atrybut -compiler ze ścieżką do kompilatora javy.</p>
<pre class="prettyprint">&gt;scomp.cmd -out library.jar library.xsd -compiler "c:\Program Files\Java\jdk1.6.0\bin\javac.exe"</pre>
<p>Tak oto uzyskany plik <em>library.jar</em> dołączamy do aplikacji i cieszymy się łatwością manipulowania danymi :) Oto kilka wskazówek dotyczących utworzonych przez XMLBeans klas:</p>
<ul>
<li>wartość z atrybutu <em>targetNamespace</em> jest nazwą pakietu (z http://xsd.j2ee.pl/library.xsd powstał pakiet pl.j2Ee.xsd.library)</li>
<li>z globalnych elementów i typów powstają zwykłe klasy i interfejsy (np klasa LibraryDocumentImpl i interfejs LibraryDocument)</li>
<li>typy anonimowe reprezentowane są przez klasy wewnętrzne</li>
<li>elementy lokalne i atrybuty zamieniane są na pola klas</li>
<li>typy proste posiadają setery i getery (znane ze specyfikacji JavaBeans)</li>
</ul>
<p>Mamy już definicje dokumentu XML w postaci pliku library.xsd. Mamy dane w pliku library-data.xml (zaprezentowane trochę wyżej). Mamy wygenerowaną, na podstawie XML Schema, bibliotekę z której będziemy korzystać w naszej aplikacji. Mamy więc już prawie wszystko. Teraz chwila radosnego programowania :)</p>
<p><strong>Wczytanie danych z pliku XML do obiektów Java</strong>. Wygenerowane interfejsy zawierają statyczną fabrykę, która pozwala stworzyć nowy obiekt implementujący dany interfejs. Można utworzyć &#8220;pusty&#8221; obiekt za pomocą metody <strong>newInstance()</strong> lub wczytać dane za pomocą metody <strong>parse()</strong>. Główne (globalne) elementy XML Schema posiadają wygenerowane dwa interfejsy i dwie ich implementacje. W przypadku elementu &lt;library&gt; są to interfejsy <em>Library</em> oraz <em>LibraryDocument</em>. Używamy implementacji interfejsu <em>LibraryDocument</em> dla elementów które są rootem drzewa XML. Dla pozostałych elementów wykorzystujemy implementacje bez końcówki &#8220;<em>Document</em>&#8220;. Metoda zaprezentowana poniżej wczytuje dane wypożyczalni z pliku XML.</p>
<pre class="prettyprint">public LibraryDocument loadData(String pathToFile) throws XmlException, IOException {
  File xmlFile = new File(pathToFile);
  LibraryDocument library = LibraryDocument.Factory.parse(xmlFile);
  return library;
}</pre>
<p><strong>Dodanie nowej książki do biblioteki</strong>. W tym momencie jesteśmy w posiadaniu obiektu implementującego interfejs <em>LibraryDocument</em>. Aby dodać to niego element book, musimy wywołać metodę <strong>addNewBook() </strong>interfejsu <em>Library</em>. Metoda ta zwraca instancję interfejsu <em>Book</em>, na którym działamy dodając do niego takie dane jak tytuł książki oraz autorów. Wartości atrybutów ustawiane są za pomocą, znanych wszystkim, seterów i geterów. Istnieją także odpowiednie metody remove***(int i) (np. removeAuthor(int i)), które pozwalają usunąć wybrany element.</p>
<pre class="prettyprint">public void addBook(LibraryDocument library) {
  pl.j2Ee.xsd.library.Book book = library.getLibrary().addNewBook();
  book.setTitle("JBoss in Action: Configuring the JBoss Application Server");
  book.setPublishYear(2007);
  Author author = book.addNewAuthor();
  author.setName("Javid");
  author.setSurname("Jamae");
  author = book.addNewAuthor();
  author.setName("Peter");
  author.setSurname("Johnson");
}</pre>
<p><strong>Wyświetlenie danych na konsoli</strong>. Ta prosta metoda pozwoli zrozumieć w jaki sposób przetrzymywane są dane naszej biblioteki. W klasie <em>LibraryImpl</em> znajduje się tablica obiektów typu <em>BookImpl</em>, a w tej ostatniej tablica obiektów <em>AuthorImpl</em>. Dzięki takiej prostej strukturze, w łatwy sposób możemy wykonać iterację po każdym elemencie biblioteki. Aby uzyskać referencję do konkretnej tablicy musimy posłużyć się metodą <strong>get***Array()</strong> (w naszym przypadku są to metody: getBookArray() i getAuthorArray()). Jeżeli interesuje nas uzyskanie Stringa z XMLem powinniśmy użyć metody <strong>xmlText()</strong> na którymkolwiek obiekcie klasy wygenerowanej przez XML Beans. Oczywiście, jeżeli metoda ta zostanie wywołana na naszym obiekcie <em>Library</em> otrzymamy cały przetwarzany XML, jeżeli wywołanie nastąpi np na obiekcie <em>Book</em>, wtedy uzyskamy tylko fragment XMLa.</p>
<pre class="prettyprint">public void printData(LibraryDocument library) {
  Book[] books = library.getLibrary().getBookArray();
  for (Book book : books) {
    System.out.println("Tytul: " + book.getTitle() + ", rok wydania: " + book.getPublishYear());
    for (Author author : book.getAuthorArray()) {
      System.out.println("    Autor: " + author.getName() + " " + author.getSurname());
    }
  }
}

public void printXml(LibraryDocument library) {
  System.out.println(library.xmlText());
}</pre>
<p><strong>Zapis biblioteki do pliku</strong>.  Ostatnią operacją wykonaną na naszej prymitywnej wypożyczalni jest zapis zmodyfikowanych danych do pliku. Służy do tego metoda <strong>save()</strong>, do której przekazujemy obiekt klasy implementującej interfejs <em>OutputStream</em> (dostępne są także inne implementacje tejże metody).</p>
<pre class="prettyprint">public void saveXmlFile(LibraryDocument library, String pathToFile) throws IOException {
  File xmlFile = new File(pathToFile);
  OutputStream os = new FileOutputStream(xmlFile);
  library.save(xmlFile);
  os.flush();
}</pre>
<p>W tym stanie zostawiam Wam ten, jakże zaawansowany, mechanizm katalogu książek. Dopracowanie go zostawiam Wam, jako pracę domową :) Udostępniam kody źródłowe aplikacji (<a href="http://j2ee.pl/wp-content/uploads/2007/10/xmlbeans.zip">klik</a>), choć właściwie nie są potrzebne, gdyż cały kod umieszczony jest w tym artykule.</p>
<p>Osobą, które zdecydują się na bliższy kontakt z XML Beans, polecam zapoznanie się z mechanizmem kursorów, który pozwala na wydajny dostęp do XML oraz umożliwia korzystanie np. z XPath.</p>
]]></content:encoded>
			<wfw:commentRss>http://j2ee.pl/2007/10/20/apache-xmlbeans-bindowanie-danych-xml-do-typow-java/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
