Commit 5050bdab by Patryk Czarnik

przykłady funkcyjne i xmlowe

parent 7d0f35fc
<osoby>
<osoba plec="K">
<imie>Ala</imie>
<nazwisko>Kowalska</nazwisko>
<dataUrodzenia>1997-08-09</dataUrodzenia>
</osoba>
<!-- komentarz -->
<osoba plec="M">
<imie>Jan</imie>
<nazwisko>Kowalski</nazwisko>
<dataUrodzenia>1999-08-07</dataUrodzenia>
</osoba>
<osoba>
<imie>Ktoś</imie>
<nazwisko>Nieokreślony</nazwisko>
</osoba>
</osoby>
\ No newline at end of file
Ala ma kota
Ola ma psa
Łukasz ma żółwia
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<sklep>
<kategoria id-kategorii="herbata">
<nazwa>Herbata</nazwa>
<opis>Herbata jest dobra.</opis>
</kategoria>
<kategoria id-kategorii="kawa">
<nazwa>Kawa</nazwa>
<opis>Kawa podobno jest niezdrowa ze względu na zawartość <term>kofeiny</term>. Ale wielu ludzi się tym nie przejmuje.</opis>
</kategoria>
<kategoria id-kategorii="czeko">
<nazwa>Czekolada</nazwa>
</kategoria>
<towar id-kategorii="herbata" id-towaru="teekane-gold">
<nazwa>Teekane Gold 80 szt.</nazwa>
<opis>
Opis z <em>wyróżnieniem</em>, <term>pojęciem</term>, <rem>uwagą</rem> oraz <link href="http://pl.wikipedia.org">odnośnikiem</link>.
<br/>
Ten fragment ma być od nowej linii.
</opis>
<cena>12</cena>
<vat>23</vat>
<cena-promocyjna od="2011-11-17" do="2011-11-18">10.99</cena-promocyjna>
</towar>
<towar id-kategorii="czeko" id-towaru="milka-m">
<nazwa>Milka mleczna</nazwa>
<opis>
Niebieskie krowy dają czekoladę. Takie rzeczy tylko w niemieckich Alpach.
</opis>
<cena>2.50</cena>
<vat>23</vat>
</towar>
<towar id-kategorii="herbata" id-towaru="lipton100">
<nazwa>Lipton 100 szt.</nazwa>
<opis>
Herbata w żółtym pudełku <em>mieszczącym 100 sztuk</em>.<br/>
Opłacalny wybór.
</opis>
<cena>12</cena>
<vat>23</vat>
<cena-promocyjna od="2011-11-20" do="2011-11-21">10.99</cena-promocyjna>
<cena-promocyjna od="2011-11-10" do="2011-11-30">10.49</cena-promocyjna>
</towar>
<towar id-kategorii="herbata" id-towaru="lipton25">
<nazwa>Lipton 25 szt.</nazwa>
<certyfikatBezpieczenstwa>123123123</certyfikatBezpieczenstwa>
<opis>
Herbata w żółtym pudełku <em>mieszczącym 25 sztuk</em>.<br/>
<em><rem>Nieco mniej</rem> opłacalny wybór</em>.
</opis>
<cena>6.50</cena>
<vat>23</vat>
</towar>
<towar id-kategorii="kawa" id-towaru="jacobs-k">
<nazwa lang="de">Jacobs Krönung</nazwa>
<opis>
Królowa kawy od <link href="http://www.coffeemoose.pl/historia-firmy-jacobs">wielu lat</link>.
</opis>
<cena>21</cena>
<vat>23</vat>
<cena-promocyjna od="2011-11-18" do="2011-04-18">16</cena-promocyjna>
</towar>
<towar id-kategorii="herbata" id-towaru="dilmah">
<nazwa>Dilmah black tea</nazwa>
<opis>
Czarna herbata Dilmah. Klasyka smaku.
</opis>
<cena>16</cena>
<vat>23</vat>
<cena-promocyjna od="2011-11-12" do="2011-11-21">17</cena-promocyjna>
</towar>
<towar id-kategorii="kawa" id-towaru="tchibo">
<nazwa>Tchibo Family</nazwa>
<opis>
Ulubiona kawa rodzinna.<br/>
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
</opis>
<cena>19</cena>
<vat>23</vat>
<cena-promocyjna od="2011-11-20" do="2011-11-21">16</cena-promocyjna>
</towar>
<towar id-kategorii="czeko" id-towaru="wedel-g">
<nazwa>Wedel gorzka</nazwa>
<opis>
Czekolada gorzka i twarda.<br/>
<rem>Uwaga na zęby</rem>
</opis>
<cena>2.20</cena>
<vat>23</vat>
<cena-promocyjna od="2011-11-14" do="2011-11-18">2.00</cena-promocyjna>
</towar>
<towar id-kategorii="czeko" id-towaru="wedel-m">
<nazwa>Wedel mleczna</nazwa>
<opis>
Jeśli ktoś lubi bardziej na słodko, czekolada mleczna będzie OK.
</opis>
<cena>2.20</cena>
<vat>23</vat>
<cena-promocyjna od="2011-11-20" do="2011-11-23">2.00</cena-promocyjna>
</towar>
<towar id-kategorii="herbata" id-towaru="ahmad">
<nazwa>Ahmad Tea</nazwa>
<opis>
Mocna czarna herbata dla wybrednych.
</opis>
<cena>13</cena>
<vat>23</vat>
</towar>
<towar id-kategorii="herbata" id-towaru="saga">
<nazwa>Saga</nazwa>
<opis>
Tania herbata dla oszczędnych. <rem>Jednak nie tak tania jak produkty w Biedronce.</rem>
</opis>
<cena>13</cena>
<vat>23</vat>
</towar>
</sklep>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="sklep"> <!-- asortyment sklepu -->
<xs:complexType>
<xs:sequence>
<xs:element name="kategoria" type="TKategoria" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="towar" type="TTowar" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:key name="KKategorieWSklepie">
<xs:selector xpath="kategoria"/>
<xs:field xpath="@id-kategorii"/>
</xs:key>
<xs:key name="KTowaryWSklepie">
<xs:selector xpath="towar"/>
<xs:field xpath="@id-towaru"/>
</xs:key>
<xs:keyref name="KKategorieZTowarow" refer="KKategorieWSklepie">
<xs:selector xpath="towar"/>
<xs:field xpath="@id-kategorii"/>
</xs:keyref>
</xs:element>
<xs:element name="cenniki"> <!-- zbiór cenników z różnych (w założeniu kolejnych) dat -->
<xs:complexType>
<xs:sequence>
<xs:element ref="cennik" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="KDatyWCennikach">
<xs:selector xpath="cennik"/>
<xs:field xpath="data"/>
</xs:unique>
</xs:element>
<xs:element name="cennik"> <!-- cennik z jednego dnia -->
<xs:complexType>
<xs:sequence>
<xs:element name="data" type="xs:date"/>
<xs:element name="towar" type="TTowar" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="KTowaryWCenniku">
<xs:selector xpath="towar"/>
<xs:field xpath="@id-towaru"/>
</xs:unique>
</xs:element>
<xs:complexType name="TKategoria">
<xs:sequence>
<xs:element name="nazwa" type="TNazwa"/>
<xs:element name="opis" type="TTekst" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id-kategorii" type="TId" use="required"/>
</xs:complexType>
<xs:complexType name="TTowar">
<xs:sequence>
<xs:element name="nazwa" type="TNazwa"/>
<xs:element name="opis" type="TTekst" minOccurs="0"/>
<xs:element name="cena" type="TKwota"/>
<xs:element name="vat" type="TVat"/>
<xs:element name="cena-promocyjna" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="TKwota">
<xs:attributeGroup ref="APrzedział"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id-towaru" type="TId" use="required"/>
<xs:attribute name="id-kategorii" type="TId"/>
</xs:complexType>
<xs:complexType name="TTekst" mixed="true">
<xs:group ref="GElementyTekstu" minOccurs="0" maxOccurs="unbounded"/>
</xs:complexType>
<xs:group name="GElementyTekstu">
<xs:choice>
<xs:element name="em" type="TTekst"/>
<xs:element name="rem" type="TTekst"/>
<xs:element name="term" type="TTekst"/>
<xs:element name="br">
<xs:complexType/>
</xs:element>
<xs:element name="link">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="href" type="xs:anyURI" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:group>
<xs:attributeGroup name="APrzedział">
<xs:attribute name="od" type="xs:date" use="required"/>
<xs:attribute name="do" type="xs:date" use="required"/>
</xs:attributeGroup>
<xs:simpleType name="TKwota">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0"/>
<xs:fractionDigits value="2"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TVat">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
<xs:fractionDigits value="0"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TNazwa">
<xs:restriction base="xs:token">
<xs:minLength value="1"/>
<xs:maxLength value="120"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TId">
<xs:restriction base="xs:token">
<xs:minLength value="1"/>
<xs:maxLength value="32"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="kategoria"/>
<xsl:output method="html" encoding="utf-8"/>
<xsl:decimal-format
decimal-separator=","
grouping-separator=" "/>
<!-- Szablon dla korzenia, uruchamiany jako pierwszy -->
<xsl:template match="/">
<html>
<head>
<title>Sklep <xsl:value-of select="$kategoria"/></title>
<style type="text/css">
body { background-color: #DDDDDD}
.kat {background-color: #DDFFFF}
.tow { background-color: #FFFFDD}
.tow, .kat {
border: 2px outset #665500;
margin: 1em auto;
padding: 0.5em;
width: 400px;
}
h2 {
margin: 0 0 0.5em 0;
}
strong { color: red }
</style>
</head>
<body>
<xsl:apply-templates select="(sklep/kategoria | sklep/towar)
[@id-kategorii = $kategoria or not($kategoria)]"/>
</body>
</html>
</xsl:template>
<xsl:template match="kategoria">
<div class="kat" id="K{@id-kategorii}">
<xsl:apply-templates select="nazwa"/>
<xsl:apply-templates select="opis"/>
<xsl:for-each select="//towar[@id-kategorii = current()/@id-kategorii]">
<a href="#T{@id-towaru}">
<xsl:value-of select="nazwa"/>
</a>
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
</div>
</xsl:template>
<xsl:template match="towar">
<div class="tow" id="T{@id-towaru}">
<!-- Sami nadajemy kolejność wypisywanym elementom -->
<xsl:apply-templates select="nazwa"/>
<xsl:variable name="moja-kategoria" select="@id-kategorii"/>
<a href="#K{@id-kategorii}">
<xsl:value-of select="//kategoria[@id-kategorii = $moja-kategoria]/nazwa"/>
</a>
<!-- Albo bez zmiennej:
<xsl:value-of select="//kategoria[@id-kategorii = current()/@id-kategorii]/nazwa"/> -->
<br/>
Cena netto:
<xsl:call-template name="kwota">
<xsl:with-param name="wartość" select="cena"/>
</xsl:call-template>
<br />
Cena brutto:
<xsl:call-template name="kwota">
<xsl:with-param name="wartość" select="cena * (1 + vat div 100)"/>
</xsl:call-template>
<xsl:apply-templates select="opis"/>
</div>
</xsl:template>
<xsl:template match="nazwa">
<h2><xsl:apply-templates/></h2>
</xsl:template>
<xsl:template match="opis">
<p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="em">
<strong><xsl:apply-templates/></strong>
</xsl:template>
<xsl:template match="term">
<dfn><xsl:apply-templates/></dfn>
</xsl:template>
<xsl:template match="link">
<a href="{@href}"><xsl:apply-templates/></a>
</xsl:template>
<xsl:template match="br">
<br/>
</xsl:template>
<xsl:template name="kwota">
<xsl:param name="wartość"/>
<xsl:value-of select="format-number($wartość, '0,00')"/>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="kategoria" />
<xsl:template match="/*">
<xsl:copy>
<xsl:copy-of select="kategoria[@id-kategorii = $kategoria or not($kategoria)]"/>
<xsl:copy-of select="towar[@id-kategorii = $kategoria or not($kategoria)]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:param name="kategoria" />
<xsl:decimal-format name="format-polski"
decimal-separator=","
grouping-separator=" "/>
<xsl:template match="/">
<html>
<head>
<title>Sklep</title>
<style type="text/css">
.towar, .kategoria {
display: block;
margin: 1em;
padding: 0.5em;
border-style: solid;
border-with: 2px;
}
.towar {
border-color: green;
}
.kategoria {
border-color: red;
}
h2 {
font-size: 1.2em;
font-family: 'Arial', sans-serif;
margin: 0 0 0.75em 0;
}
.kategoria h2 {
font-style: italic;
font-weight: normal;
}
.towar h2 {
font-style: normal;
font-weight: bold;
}
dfn {
font-weight: bold;
font-style: normal;
}
span.rem {
color: #888888;
}
</style>
</head>
<body>
Towary z kategorii: <xsl:value-of select="$kategoria"/>
<xsl:apply-templates select="/sklep/kategoria[@id-kategorii = $kategoria or not($kategoria)]"/>
<xsl:apply-templates select="/sklep/towar[@id-kategorii = $kategoria or not($kategoria)]"/>
</body>
</html>
</xsl:template>
<xsl:template match="kategoria">
<div class="kategoria" id="K-{@id-kategorii}">
<xsl:apply-templates select="nazwa"/>
<xsl:apply-templates select="opis"/>
<p>Towary:
<xsl:for-each select="/sklep/towar[@id-kategorii = current()/@id-kategorii]">
<a href="#T-{@id-towaru}"><xsl:value-of select="nazwa"/></a>
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
</p>
</div>
</xsl:template>
<xsl:template match="towar">
<div class="towar" id="T-{@id-towaru}">
<xsl:apply-templates select="nazwa"/>
Kategoria:
<a href="#K-{@id-kategorii}">
<xsl:value-of select="/sklep/kategoria[@id-kategorii = current()/@id-kategorii]/nazwa"/>
</a>
<p>
<xsl:if test="cena-promocyjna">
PROMOCJA<br/>
</xsl:if>
Cena netto: <xsl:value-of select="format-number(cena, '0,00', 'format-polski')"/>
<br/>
Cena brutto: <xsl:value-of select="format-number(cena * (1 + vat div 100), '0,00', 'format-polski')"/>
</p>
<xsl:apply-templates select="opis"/>
</div>
</xsl:template>
<xsl:template match="nazwa">
<h2>
<xsl:apply-templates />
</h2>
</xsl:template>
<xsl:template match="opis">
<p>
<xsl:apply-templates />
</p>
</xsl:template>
<xsl:template match="term">
<dfn>
<xsl:apply-templates />
</dfn>
</xsl:template>
<xsl:template match="em">
<em>
<xsl:apply-templates />
</em>
</xsl:template>
<xsl:template match="rem">
<span class="rem">
<xsl:apply-templates />
</span>
</xsl:template>
<xsl:template match="link">
<a href="{@href}">
<xsl:apply-templates />
</a>
</xsl:template>
</xsl:stylesheet>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:s="urn:sklep">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:param name="kategoria" />
<xsl:decimal-format name="format-polski"
decimal-separator=","
grouping-separator=" "/>
<xsl:template match="/">
<html>
<head>
<title>Sklep</title>
<style type="text/css">
.towar, .kategoria {
display: block;
margin: 1em;
padding: 0.5em;
border-style: solid;
border-with: 2px;
}
.towar {
border-color: green;
}
.kategoria {
border-color: red;
}
h2 {
font-size: 1.2em;
font-family: 'Arial', sans-serif;
margin: 0 0 0.75em 0;
}
.kategoria h2 {
font-style: italic;
font-weight: normal;
}
.towar h2 {
font-style: normal;
font-weight: bold;
}
dfn {
font-weight: bold;
font-style: normal;
}
span.rem {
color: #888888;
}
</style>
</head>
<body>
Towary z kategorii: <xsl:value-of select="$kategoria"/>
<xsl:apply-templates select="/s:sklep/s:kategoria[@id-kategorii = $kategoria or not($kategoria)]"/>
<xsl:apply-templates select="/s:sklep/s:towar[@id-kategorii = $kategoria or not($kategoria)]"/>
</body>
</html>
</xsl:template>
<xsl:template match="s:kategoria">
<div class="kategoria" id="K-{@id-kategorii}">
<xsl:apply-templates select="s:nazwa"/>
<xsl:apply-templates select="s:opis"/>
<p>Towary:
<xsl:for-each select="/s:sklep/s:towar[@id-kategorii = current()/@id-kategorii]">
<a href="#T-{@id-towaru}"><xsl:value-of select="s:nazwa"/></a>
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
</p>
</div>
</xsl:template>
<xsl:template match="s:towar">
<div class="towar" id="T-{@id-towaru}">
<xsl:apply-templates select="s:nazwa"/>
Kategoria:
<a href="#K-{@id-kategorii}">
<xsl:value-of select="/s:sklep/s:kategoria[@id-kategorii = current()/@id-kategorii]/s:nazwa"/>
</a>
<p>
Cena netto: <xsl:value-of select="format-number(s:cena, '0,00', 'format-polski')"/>
<br/>
Cena brutto: <xsl:value-of select="format-number(s:cena-brutto, '0,00', 'format-polski')"/>
</p>
<xsl:apply-templates select="s:opis"/>
</div>
</xsl:template>
<xsl:template match="s:nazwa">
<h2>
<xsl:apply-templates />
</h2>
</xsl:template>
<xsl:template match="s:opis">
<p>
<xsl:apply-templates />
</p>
</xsl:template>
<xsl:template match="s:term">
<dfn>
<xsl:apply-templates />
</dfn>
</xsl:template>
<xsl:template match="s:em">
<em>
<xsl:apply-templates />
</em>
</xsl:template>
<xsl:template match="s:rem">
<span class="rem">
<xsl:apply-templates />
</span>
</xsl:template>
<xsl:template match="s:link">
<a href="{@href}">
<xsl:apply-templates />
</a>
</xsl:template>
</xsl:stylesheet>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<sklep xmlns="urn:sklep" xmlns:pre="urn:sklep"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:sklep sklep_ns.xsd">
<kategoria id-kategorii="herbata">
<nazwa>Herbata</nazwa>
<opis>Herbata jest dobra.</opis>
</kategoria>
<pre:kategoria id-kategorii="kawa">
<nazwa>Kawa</nazwa>
<opis>Kawa podobno jest niezdrowa ze względu na zawartość <term>kofeiny</term>. Ale wielu ludzi się tym nie przejmuje.</opis>
</pre:kategoria>
<kategoria id-kategorii="czeko">
<nazwa>Czekolada</nazwa>
</kategoria>
<towar id-kategorii="herbata" id-towaru="teekane-gold">
<nazwa>Teekane Gold 80 szt.</nazwa>
<opis>
Opis z <em>wyróżnieniem</em>, <term>ważnym pojęciem</term>, <rem>uwagą</rem> oraz <link href="http://pl.wikipedia.org">odnośnikiem</link>.
<br/>
Ten fragment ma być od nowej linii (albo w następnym akapicie...).
</opis>
<pre:cena>12</pre:cena>
<vat>23</vat>
<cena-promocyjna od="2011-04-20" do="2011-04-21">10.99</cena-promocyjna>
</towar>
<towar id-kategorii="czeko" id-towaru="milka-m">
<nazwa>Milka mleczna</nazwa>
<opis>
Niebieskie krowy produkują czekoladę. Takie rzeczy tylko w niemieckich (?) Alpach.
</opis>
<cena>2.50</cena>
<vat>23</vat>
</towar>
<towar id-kategorii="herbata" id-towaru="lipton100">
<nazwa>Lipton 100 szt.</nazwa>
<opis>
Herbata w żółtym pudełku <em>mieszczącym 100 sztuk</em>.<br/>
Opłacalny wybór.
</opis>
<cena>12</cena>
<vat>23</vat>
<cena-promocyjna od="2011-04-20" do="2011-04-21">10.99</cena-promocyjna>
<cena-promocyjna od="2011-04-21" do="2011-04-25">10.49</cena-promocyjna>
</towar>
<towar id-kategorii="herbata" id-towaru="lipton25">
<nazwa>Lipton 25 szt.</nazwa>
<opis>
Herbata w żółtym pudełku <em>mieszczącym 25 sztuk</em>.<br/>
<em><rem>Nieco mniej</rem> opłacalny wybór</em>.
</opis>
<cena>6.50</cena>
<vat>23</vat>
</towar>
<towar id-kategorii="kawa" id-towaru="jacobs-k">
<nazwa>Jacobs Krönung</nazwa>
<opis>
Królowa kawy od <link href="http://www.coffeemoose.pl/historia-firmy-jacobs">wielu lat</link>.
</opis>
<cena>21</cena>
<vat>23</vat>
<cena-promocyjna od="2011-04-20" do="2011-04-21">16</cena-promocyjna>
</towar>
<towar id-kategorii="herbata" id-towaru="dilmah">
<nazwa>Dilmah black tea</nazwa>
<opis>
Czarna herbata Dilmah. Klasyka smaku.
</opis>
<cena>16</cena>
<vat>23</vat>
<cena-promocyjna od="2011-04-20" do="2011-04-21">17</cena-promocyjna>
</towar>
<towar id-kategorii="kawa" id-towaru="tchibo">
<nazwa>Tchibo Family</nazwa>
<opis>
Ulubiona kawa rodzinna.<br/>
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
Ala ma kota a Ola ma psa. Ala z Olą lubią się jak pies z kotem.
</opis>
<cena>19</cena>
<vat>23</vat>
<cena-promocyjna od="2011-04-20" do="2011-04-21">16</cena-promocyjna>
</towar>
<towar id-kategorii="czeko" id-towaru="wedel-g">
<nazwa>Wedel gorzka</nazwa>
<opis>
Czekolada gorzka i twarda.<br/>
<rem>Uwaga na zęby</rem>
</opis>
<cena>2.20</cena>
<vat>23</vat>
<cena-promocyjna od="2011-04-21" do="2011-04-23">2.00</cena-promocyjna>
</towar>
<towar id-kategorii="czeko" id-towaru="wedel-m">
<nazwa>Wedel mleczna</nazwa>
<opis>
Jeśli ktoś lubi bardziej na słodko, czekolada mleczna będzie OK.
</opis>
<cena>2.20</cena>
<vat>23</vat>
<cena-promocyjna od="2011-04-21" do="2011-04-23">2.00</cena-promocyjna>
</towar>
<towar id-kategorii="herbata" id-towaru="ahmad">
<nazwa>Ahmad Tea</nazwa>
<opis>
Mocna czarna herbata dla wybrednych.
</opis>
<cena>13</cena>
<vat>23</vat>
</towar>
<towar id-kategorii="herbata" id-towaru="saga">
<nazwa>Saga</nazwa>
<opis>
Tania herbata dla oszczędnych. <rem>Jednak nie tak tania jak produkty w Biedronce.</rem>
</opis>
<cena>13</cena>
<vat>23</vat>
</towar>
</sklep>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
targetNamespace="urn:sklep" xmlns:tns="urn:sklep">
<xs:element name="sklep"> <!-- asortyment sklepu -->
<xs:complexType>
<xs:sequence>
<xs:element name="kategoria" type="tns:TKategoria" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="towar" type="tns:TTowar" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:key name="KKategorieWSklepie">
<xs:selector xpath="tns:kategoria"/>
<xs:field xpath="@id-kategorii"/>
</xs:key>
<xs:key name="KTowaryWSklepie">
<xs:selector xpath="tns:towar"/>
<xs:field xpath="@id-towaru"/>
</xs:key>
<xs:keyref name="KKategorieZTowarow" refer="tns:KKategorieWSklepie">
<xs:selector xpath="tns:towar"/>
<xs:field xpath="@id-kategorii"/>
</xs:keyref>
</xs:element>
<xs:element name="cenniki"> <!-- zbiór cenników z różnych (w założeniu kolejnych) dat -->
<xs:complexType>
<xs:sequence>
<xs:element ref="tns:cennik" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="KDatyWCennikach">
<xs:selector xpath="tns:cennik"/>
<xs:field xpath="tns:data"/>
</xs:unique>
</xs:element>
<xs:element name="cennik"> <!-- cennik z jednego dnia -->
<xs:complexType>
<xs:sequence>
<xs:element name="data" type="xs:date"/>
<xs:element name="towar" type="tns:TTowar" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="KTowaryWCenniku">
<xs:selector xpath="tns:towar"/>
<xs:field xpath="@id-towaru"/>
</xs:unique>
</xs:element>
<xs:complexType name="TKategoria">
<xs:sequence>
<xs:element name="nazwa" type="tns:TNazwa"/>
<xs:element name="opis" type="tns:TTekst" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id-kategorii" type="tns:TId" use="required"/>
</xs:complexType>
<xs:complexType name="TTowar">
<xs:sequence>
<xs:element name="nazwa" type="tns:TNazwa"/>
<xs:element name="opis" type="tns:TTekst" minOccurs="0"/>
<xs:element name="cena" type="tns:TKwota"/>
<xs:element name="cena-brutto" type="tns:TKwota" minOccurs="0"/>
<xs:element name="vat" type="tns:TVat"/>
<xs:element name="cena-promocyjna" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="tns:TKwota">
<xs:attributeGroup ref="tns:APrzedział"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id-towaru" type="tns:TId" use="required"/>
<xs:attribute name="id-kategorii" type="tns:TId"/>
</xs:complexType>
<xs:complexType name="TTekst" mixed="true">
<xs:group ref="tns:GElementyTekstu" minOccurs="0" maxOccurs="unbounded"/>
</xs:complexType>
<xs:group name="GElementyTekstu">
<xs:choice>
<xs:element name="em" type="tns:TTekst"/>
<xs:element name="rem" type="tns:TTekst"/>
<xs:element name="term" type="tns:TTekst"/>
<xs:element name="br">
<xs:complexType/>
</xs:element>
<xs:element name="link">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="href" type="xs:anyURI" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:group>
<xs:attributeGroup name="APrzedział">
<xs:attribute name="od" type="xs:date" use="required"/>
<xs:attribute name="do" type="xs:date" use="required"/>
</xs:attributeGroup>
<xs:simpleType name="TKwota">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0"/>
<xs:fractionDigits value="2"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TVat">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
<xs:fractionDigits value="0"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TNazwa">
<xs:restriction base="xs:token">
<xs:minLength value="1"/>
<xs:maxLength value="120"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TId">
<xs:restriction base="xs:token">
<xs:minLength value="1"/>
<xs:maxLength value="32"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfExchangeRatesTable xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ExchangeRatesTable>
<Table>A</Table>
<No>207/A/NBP/2024</No>
<EffectiveDate>2024-10-23</EffectiveDate>
<Rates>
<Rate>
<Currency>bat (Tajlandia)</Currency>
<Code>THB</Code>
<Mid>0.1192</Mid>
</Rate>
<Rate>
<Currency>dolar amerykański</Currency>
<Code>USD</Code>
<Mid>4.0176</Mid>
</Rate>
<Rate>
<Currency>dolar australijski</Currency>
<Code>AUD</Code>
<Mid>2.6752</Mid>
</Rate>
<Rate>
<Currency>dolar Hongkongu</Currency>
<Code>HKD</Code>
<Mid>0.5170</Mid>
</Rate>
<Rate>
<Currency>dolar kanadyjski</Currency>
<Code>CAD</Code>
<Mid>2.9062</Mid>
</Rate>
<Rate>
<Currency>dolar nowozelandzki</Currency>
<Code>NZD</Code>
<Mid>2.4218</Mid>
</Rate>
<Rate>
<Currency>dolar singapurski</Currency>
<Code>SGD</Code>
<Mid>3.0446</Mid>
</Rate>
<Rate>
<Currency>euro</Currency>
<Code>EUR</Code>
<Mid>4.3344</Mid>
</Rate>
<Rate>
<Currency>forint (Węgry)</Currency>
<Code>HUF</Code>
<Mid>0.01079</Mid>
</Rate>
<Rate>
<Currency>frank szwajcarski</Currency>
<Code>CHF</Code>
<Mid>4.6360</Mid>
</Rate>
<Rate>
<Currency>funt szterling</Currency>
<Code>GBP</Code>
<Mid>5.2168</Mid>
</Rate>
<Rate>
<Currency>hrywna (Ukraina)</Currency>
<Code>UAH</Code>
<Mid>0.0973</Mid>
</Rate>
<Rate>
<Currency>jen (Japonia)</Currency>
<Code>JPY</Code>
<Mid>0.02636</Mid>
</Rate>
<Rate>
<Currency>korona czeska</Currency>
<Code>CZK</Code>
<Mid>0.1718</Mid>
</Rate>
<Rate>
<Currency>korona duńska</Currency>
<Code>DKK</Code>
<Mid>0.5811</Mid>
</Rate>
<Rate>
<Currency>korona islandzka</Currency>
<Code>ISK</Code>
<Mid>0.029031</Mid>
</Rate>
<Rate>
<Currency>korona norweska</Currency>
<Code>NOK</Code>
<Mid>0.3665</Mid>
</Rate>
<Rate>
<Currency>korona szwedzka</Currency>
<Code>SEK</Code>
<Mid>0.3796</Mid>
</Rate>
<Rate>
<Currency>lej rumuński</Currency>
<Code>RON</Code>
<Mid>0.8714</Mid>
</Rate>
<Rate>
<Currency>lew (Bułgaria)</Currency>
<Code>BGN</Code>
<Mid>2.2161</Mid>
</Rate>
<Rate>
<Currency>lira turecka</Currency>
<Code>TRY</Code>
<Mid>0.1174</Mid>
</Rate>
<Rate>
<Currency>nowy izraelski szekel</Currency>
<Code>ILS</Code>
<Mid>1.0601</Mid>
</Rate>
<Rate>
<Currency>peso chilijskie</Currency>
<Code>CLP</Code>
<Mid>0.004238</Mid>
</Rate>
<Rate>
<Currency>peso filipińskie</Currency>
<Code>PHP</Code>
<Mid>0.0693</Mid>
</Rate>
<Rate>
<Currency>peso meksykańskie</Currency>
<Code>MXN</Code>
<Mid>0.2007</Mid>
</Rate>
<Rate>
<Currency>rand (Republika Południowej Afryki)</Currency>
<Code>ZAR</Code>
<Mid>0.2280</Mid>
</Rate>
<Rate>
<Currency>real (Brazylia)</Currency>
<Code>BRL</Code>
<Mid>0.7060</Mid>
</Rate>
<Rate>
<Currency>ringgit (Malezja)</Currency>
<Code>MYR</Code>
<Mid>0.9236</Mid>
</Rate>
<Rate>
<Currency>rupia indonezyjska</Currency>
<Code>IDR</Code>
<Mid>0.00025721</Mid>
</Rate>
<Rate>
<Currency>rupia indyjska</Currency>
<Code>INR</Code>
<Mid>0.047787</Mid>
</Rate>
<Rate>
<Currency>won południowokoreański</Currency>
<Code>KRW</Code>
<Mid>0.002906</Mid>
</Rate>
<Rate>
<Currency>yuan renminbi (Chiny)</Currency>
<Code>CNY</Code>
<Mid>0.5637</Mid>
</Rate>
<Rate>
<Currency>SDR (MFW)</Currency>
<Code>XDR</Code>
<Mid>5.3316</Mid>
</Rate>
</Rates>
</ExchangeRatesTable>
</ArrayOfExchangeRatesTable>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -12,7 +12,7 @@ public class F5_MiastaBezPowtorzen {
// ma to sens, gdy potrzebujemy wykorzystać te dane w dalszej części programu
Set<String> miasta = emps.stream()
.map(Employee::getCity)
.collect(Collectors.toSet());
.collect(Collectors.toSet()); // można też Collectors.toCollection(TreeSet::new)
System.out.println(miasta);
System.out.println("--------");
......
......@@ -3,7 +3,7 @@ package emps;
import java.util.Comparator;
import java.util.List;
public class F6_MinMax {
public class F6_MinMax_v1 {
public static void main(String[] args) {
List<Employee> emps = ObslugaCSV.wczytaj("emps.csv");
......
package emps;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
public class F6_MinMax_v2 {
public static void main(String[] args) {
List<Employee> lista = ObslugaCSV.wczytaj();
Optional<Employee> min = lista.stream().min(Comparator.comparing(Employee::getSalary));
Optional<Employee> max = lista.stream().max(Comparator.comparing(Employee::getSalary));
System.out.println("min: " + min);
System.out.println("max: " + max);
System.out.println();
if(min.isPresent()) {
System.out.println("Znaleziono minimum:");
Employee emp = min.get();
System.out.println(emp.getFirstName() + " " + emp.getLastName() + " zarabia " + emp.getSalary());
} else {
System.out.println("nie ma minimum");
}
if(max.isPresent()) {
System.out.println("Znaleziono maximum:");
Employee emp = max.get();
System.out.println(emp.getFirstName() + " " + emp.getLastName() + " zarabia " + emp.getSalary());
} else {
System.out.println("nie ma maximum");
}
System.out.println();
String [] stanowiska = {"Programmer", "Shipping Clerk", "Brygadier"};
for (String stanowisko : stanowiska) {
String tekst = lista.stream()
.filter(emp -> Objects.equals(emp.getJobTitle(), stanowisko))
.max(Comparator.comparing(Employee::getSalary))
.map(emp -> emp.getFirstName() + " " + emp.getLastName() + " zarabia " + emp.getSalary())
.orElse("nie ma takiego gościa");
// powyższe map dotyczy Optional, a nie Stream
System.out.println("Najbogatszy " + stanowisko + ": " + tekst);
}
}
}
package emps;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.Scanner;
public class F8_DaneOpcjonalne {
public static void main(String[] args) {
// Użytkownik podaje nazwę miasta, a program filtruje dane wczytane z pliku
// i oblicza średnią pensję oraz znajduje najbogatszego i najbiedniejszego pracownika.
// Przykład ma pokazać, jak można wykorzystać wyniki typu Optional.
Scanner scanner = new Scanner(System.in);
System.out.print("Podaj nazwę miasta: ");
String miasto = scanner.nextLine();
List<Employee> emps = ObslugaCSV.wczytaj();
OptionalDouble srednia = emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.mapToInt(Employee::getSalary)
.average();
Optional<Employee> min = emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.min(Comparator.comparingInt(Employee::getSalary));
Optional<Employee> max = emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.max(Comparator.comparingInt(Employee::getSalary));
System.out.println("średnia" + srednia);
System.out.println("min: " + min);
System.out.println("max: " + max);
System.out.println();
// Za pomocą isPresent / isEmpty można sprawdzać, czy obiekt zawiera wartość
if(srednia.isPresent()) {
// aby wydobyć liczbę z obiektu, piszemy getAsDouble (w przypadku pustego Optionala kończy się to błędem)
System.out.println("Średnia pensja = " + srednia.getAsDouble());
} else {
System.out.println("Brak danych");
}
System.out.println();
if(min.isPresent()) {
// aby dostać się do obiektu wewnątrz Optionala, piszemy get(); w razie braku danych powoduje to błąd
Employee emp = min.get();
System.out.println("Najbiedniejszy: " + emp.getFirstName() + " " + emp.getLastName() + " z pensją " + emp.getSalary());
} else {
System.out.println("Brak danych");
}
if(max.isEmpty()) {
System.out.println("Brak danych");
} else {
Employee emp = max.get();
System.out.println("Najbogatszy: " + emp.getFirstName() + " " + emp.getLastName() + " z pensją " + emp.getSalary());
}
System.out.println();
// Operacja orElse zwraca wartość z wnętrza Optionala, a w razie braku danych zwraca wartość alternatywną podaną w nawiasach
System.out.println("srednia.orElse(0) = " + srednia.orElse(0));
System.out.println("srednia.orElse(NaN) = " + srednia.orElse(Double.NaN));
// W przypadku obiektów użycie orElse wymagałoby posiadania "domyślnego pracownika", ew. można wstawić nulla
Employee fejkowy = new Employee(0, "Fejkowy", "Pracownik", "nikt", -1, null, "", "", "", "", "nieznany kraj");
System.out.println("najbiedniejszy lub zmyślony:");
System.out.println(min.orElse(fejkowy));
System.out.println("najbogatszy lub null:");
System.out.println(max.orElse(null));
System.out.println();
// Domyślnym wyjątkiem wyrzucanym w razie braku danych gdy robimy get jest NoSuchElementException
// System.out.println("Najbogatsza osoba to " + max.get().getLastName());
// ale możemy wyrzuć własny dedykowany wyjątek
// Podajemy to w formie lambdy, aby kod tworzący wyjątek został wykonany tylko wtedy, gdy jest naprawdę potrzebny
// String nazwisko = max.orElseThrow(() -> new RuntimeException("wielka bieda")).getLastName();
// System.out.println("Najbogatsza osoba to " + nazwisko);
// Na obiektach Optional (i w mniejszym stoniu na ich wersjach liczbowych) można wykonywać operacje
// przypominające operacje na strumieniach.
// Operacja map z Optionala jednego typu jest w stanie utworzyc Optional innego typu
// Na podstawie Optional<Employee> utworzymy Optional<String> zawierający dane pracownika
Optional<String> minTXT = min.map(emp -> "Najbiednieszy jest " + emp.getFirstName() + " " + emp.getLastName());
// Jeśli min był pusty, to minTXT też będzie pusty
// Jeśli min zawierał dane pracownika, to minTXT będzie zawierał tekst z imieniem i nazwiskiem pracownika
System.out.println("Optional<String>: " + minTXT);
// Można to wykorzystać w zapisie typu pipeline w taki sposób:
String maxTXT = emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.max(Comparator.comparingInt(Employee::getSalary))
.map(emp -> "Najbogatszy jest " + emp.getFirstName() + " " + emp.getLastName())
.orElse("Brak danych najbogatszego");
System.out.println("maxTXT: " + maxTXT);
// czasami może się zdarzyć, że wartość alternatywna jest obliczana w trakcie działania programu
// aby uniknąć niepotrzebnego obliczania (aby robić to tylko w przypadku braku danych), można podać wyrażenie lambda tworzące ten wynik
String maxTXT2 = emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.max(Comparator.comparingInt(Employee::getSalary))
.map(emp -> "Najbogatszy jest " + emp.getFirstName() + " " + emp.getLastName())
.orElseGet(() -> "Brak najbogatszego w mieście " + miasto);
System.out.println("maxTXT2: " + maxTXT2);
// Można też podać akcję, która zostanie wykonana tylko, gdy optional nie jest pusty
min.ifPresent(emp -> System.out.println("Znaleziony najbiedniejszy pracownik! - " + emp.getFirstName() + " " + emp.getLastName()));
// wersja z else (co zrobić w razie braku danych)
max.ifPresentOrElse(
emp -> System.out.println("Znaleziony najbogatszy pracownik! - " + emp.getFirstName() + " " + emp.getLastName()),
() -> System.out.println("Nie znaleziomo najbogatszego!"));
// oczywiście można to zastosować na końcu pipeline
emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.mapToInt(Employee::getSalary)
.average()
.ifPresentOrElse(
avg -> System.out.println("Jest średnia " + avg),
() -> System.out.println("Nie ma średniej"));
}
}
......@@ -8,13 +8,11 @@ public class F9_Podwyzka {
public static void main(String[] args) {
List<Employee> emps = ObslugaCSV.wczytaj("emps.csv");
emps.stream()
.filter(emp -> "Programmer".equals(emp.getJobTitle()))
.forEach(emp -> emp.setSalary(emp.getSalary() + 3333));
emps.forEach(emp -> System.out.println(emp.getFirstName() + " " + emp.getLastName() + " (" + emp.getJobTitle() + ") : " + emp.getSalary()));
ObslugaCSV.zapisz(emps, "zmodyfikowany2.csv");
}
......
package gotowe.p25_kolekcje.zbieranie_danych;
import java.util.Arrays;
import java.util.Scanner;
public class P1_Tablica {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Podczas tworzenia tablicy musimy wiedzieć, ile elementów ma mieć.
System.out.print("Ile imion podasz? ");
int size = scanner.nextInt();
scanner.nextLine(); // ingorujemy resztę linii, co ma znaczenie nawet, jeśli jest pusta
String[] tablica = new String[size];
for(int i = 0; i < tablica.length; i++) {
System.out.print("Podaj imię nr " + i + ": ");
String imie = scanner.nextLine();
tablica[i] = imie;
}
System.out.println(Arrays.toString(tablica));
System.out.println();
// Drugi etap: użytkownik podaje numer, a program odczytuje wartość z podanej pozycji.
// -1 kończy
while(true) {
System.out.print("Podaj nr pozycji: ");
int pozycja = scanner.nextInt();
scanner.nextLine();
if(pozycja == -1) {
break;
}
try {
String imie = tablica[pozycja];
System.out.println("Osoba nr " + pozycja + " to " + imie);
} catch (Exception e) {
System.out.println(e);
}
}
}
}
package gotowe.p25_kolekcje.zbieranie_danych;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.print.attribute.standard.Sides;
public class P2_Lista {
// Listy:
// - mogą zawierać duplikaty (tę wartość kilka razy),
// - przechowują elementy na określonych pozycjach od 0 do size-1,
// za pomocą get(i) można odczytać, a za pomocą set(i, nowaWartosc) zmienić konkretny element listy
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Gdy używamy listy nie musimy z wyprzedzeniem znać jej rozmiaru.
// Do listy zawsze można dodać kolejny element na końcu (*)
// (*) - realnymi ograniczeniami są: 1) rozmiar int, 2) dostępna pamięć
List<String> lista = new ArrayList<>();
while(true) {
System.out.print("Podaj imię: ");
// pusty String oznacza koniec
String imie = scanner.nextLine();
if(imie.isEmpty()) {
break;
}
lista.add(imie);
}
System.out.println("Liczba odczytanych elementów: " + lista.size());
System.out.println(lista);
System.out.println();
// Drugi etap: użytkownik podaje numer, a program odczytuje wartość z podanej pozycji.
// -1 kończy
while(true) {
System.out.print("Podaj nr pozycji: ");
int pozycja = scanner.nextInt();
scanner.nextLine();
if(pozycja == -1) {
break;
}
try {
String imie = lista.get(pozycja);
System.out.println("Osoba nr " + pozycja + " to " + imie);
} catch (Exception e) {
System.out.println(e);
}
}
}
}
package gotowe.p25_kolekcje.zbieranie_danych;
import java.text.Collator;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.print.attribute.standard.Sides;
public class P2_Lista_Sortowanie {
// Listy:
// - mogą zawierać duplikaty (tę wartość kilka razy),
// - przechowują elementy na określonych pozycjach od 0 do size-1,
// za pomocą get(i) można odczytać, a za pomocą set(i, nowaWartosc) zmienić konkretny element listy
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Gdy używamy listy nie musimy z wyprzedzeniem znać jej rozmiaru.
// Do listy zawsze można dodać kolejny element na końcu (*)
// (*) - realnymi ograniczeniami są: 1) rozmiar int, 2) dostępna pamięć
List<String> lista = new ArrayList<>();
while(true) {
System.out.print("Podaj imię: ");
// pusty String oznacza koniec
String imie = scanner.nextLine();
if(imie.isEmpty()) {
break;
}
lista.add(imie);
}
System.out.println("Liczba odczytanych elementów: " + lista.size());
System.out.println(lista);
System.out.println("Sortowanie...");
lista.sort(Collator.getInstance());
System.out.println(lista);
System.out.println();
// Drugi etap: użytkownik podaje numer, a program odczytuje wartość z podanej pozycji.
// -1 kończy
while(true) {
System.out.print("Podaj nr pozycji: ");
int pozycja = scanner.nextInt();
scanner.nextLine();
if(pozycja == -1) {
break;
}
try {
String imie = lista.get(pozycja);
System.out.println("Osoba nr " + pozycja + " to " + imie);
} catch (Exception e) {
System.out.println(e);
}
}
}
}
package gotowe.p25_kolekcje.zbieranie_danych;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class P3_HashSet {
// Zbiory:
// - nie zawierają duplikatów (dodanie kolejny raz tej samej wartości nie zmienia już zbioru),
// - mają prawo zmienić kolejność elementów
// → HashSet zmienia kolejność (wg własnych zasad w oparciu o haszkody, na co nie mamy wpływu)
// → LinkedHashSet nie zmienia kolejności (zachowuje początkową kolejność, w jakiej elementy były dodawane)
// → TreeSet samoczynnie sortuje elementy
// Podstawową (i wydajną) operacją dla zbioru jest sprawdzenie czy element należy do zbioru.
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Set<String> zbior = new HashSet<>();
while(true) {
System.out.print("Podaj imię: ");
// pusty String oznacza koniec
String imie = scanner.nextLine();
if(imie.isEmpty()) {
break;
}
zbior.add(imie);
}
System.out.println(zbior);
System.out.println();
// Drugi etap: użytkownik podaje imię, a program sprawdza, czy takie imię istnieje - to jest najbardziej podstawowa operacja dla zbiorów.
// pusty string kończy
while(true) {
System.out.print("Podaj imię: ");
String imie = scanner.nextLine();
if(imie.isEmpty()) {
break;
}
if(zbior.contains(imie)) {
System.out.println("TAK");
} else {
System.out.println("NIE");
}
}
}
}
package gotowe.p25_kolekcje.zbieranie_danych;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class P4_TreeSet {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Set<String> zbior = new TreeSet<>();
while(true) {
System.out.print("Podaj imię: ");
// pusty String oznacza koniec
String imie = scanner.nextLine();
if(imie.isEmpty()) {
break;
}
zbior.add(imie);
}
System.out.println(zbior);
System.out.println();
// Drugi etap: użytkownik podaje imię, a program sprawdza, czy takie imię istnieje - to jest najbardziej podstawowa operacja dla zbiorów.
// pusty string kończy
while(true) {
System.out.print("Podaj imię: ");
String imie = scanner.nextLine();
if(imie.isEmpty()) {
break;
}
if(zbior.contains(imie)) {
System.out.println("TAK");
} else {
System.out.println("NIE");
}
}
}
}
package gotowe.p25_kolekcje.zbieranie_danych;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class P5_HashMap {
// Słowniki (mapy):
// - zawierają pary klucz → wartość
// - klucze nie mogą się powtarzać, wartości mogą
// - wydajne są operacje dodawanie elementu i pobierania/wyszukiwania poprzez klucz
// - niewydaje jest wyszukiwanie poprzez wartość
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// W tym słowniku dla imienia osoby pamiętamy wiek tej osoby.
// String (mię) jest kluczem, Integer (wiek) jest wartością.
Map<String, Integer> slownik = new HashMap<>();
while(true) {
System.out.print("Podaj imię: ");
// pusty String oznacza koniec
String imie = scanner.nextLine();
if(imie.isEmpty()) {
break;
}
System.out.print("Podaj wiek: ");
int wiek = scanner.nextInt();
scanner.nextLine();
slownik.put(imie, wiek);
}
System.out.println(slownik);
System.out.println();
// Drugi etap: użytkownik podaje imię, a program odczytuje wartość ze słownika (czyli wiek tej osoby)
while(true) {
System.out.print("Podaj imię: ");
String imie = scanner.nextLine();
if(imie.isEmpty()) {
break;
}
// podstawową operacją do odczytywania danych ze słownika jest get(klucz)
// jeśli istnieje wpis o podanym kluczu, to wynikiem jest wartość spod tego klucza
// jeśli nie istnieje, to wynikiem jest null
// w związku z tym gdy czytamy dane ze słownika bez wcześniejszego sprawdzenia, czy klucz istnieje,
// trzeba użyć zmiennej typu obiektowego (tutaj Integer, a nie int)
Integer wiek = slownik.get(imie);
if(wiek == null) {
System.out.println("W słowniku nie osoby " + imie);
} else {
System.out.println("Osoba " + imie + " ma " + wiek + " lat");
}
// Można też użyć operacji containsKey do sprawdzenia, czy słownik zawiera podany klucz
// if(slownik.containsKey(imie)) {
// System.out.println("Osoba " + imie + " ma " + slownik.get(imie) + " lat.");
// } else {
// System.out.println("W słowniku nie osoby " + imie);
// }
}
}
}
package gotowe.p25_kolekcje.zbieranie_danych;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
public class P6_TreeMap {
// Podobnie, jak w przypadku zbiorów (Set), dla słowników (Map) mamy takie implementacje,
// które róznią się kolejnością danych:
// - HashMap - kolejność techniczna / chaotyczna
// - LinkedHashMap - kolejność, w jakiej elementy były dodawane po raz pierwszy
// - TreeMap - dane posortowane wg kluczy
// W zaawansowanych zastosowaniach ważną implementacją słowników jest ConcurrentHashMap,
// która poprawnie i wydajnie działa w aplikacjach wielowątkowych (rózne wątki mogą korzytać jednocześnie).
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// W tym słowniku dla imienia osoby pamiętamy wiek tej osoby.
// String (mię) jest kluczem, Integer (wiek) jest wartością.
Map<String, Integer> slownik = new TreeMap<>();
while(true) {
System.out.print("Podaj imię: ");
// pusty String oznacza koniec
String imie = scanner.nextLine();
if(imie.isEmpty()) {
break;
}
System.out.print("Podaj wiek: ");
int wiek = scanner.nextInt();
scanner.nextLine();
slownik.put(imie, wiek);
}
System.out.println(slownik);
System.out.println();
// Drugi etap: użytkownik podaje imię, a program odczytuje wartość ze słownika (czyli wiek tej osoby)
while(true) {
System.out.print("Podaj imię: ");
String imie = scanner.nextLine();
if(imie.isEmpty()) {
break;
}
// podstawową operacją do odczytywania danych ze słownika jest get(klucz)
// jeśli istnieje wpis o podanym kluczu, to wynikiem jest wartość spod tego klucza
// jeśli nie istnieje, to wynikiem jest null
// w związku z tym gdy czytamy dane ze słownika bez wcześniejszego sprawdzenia, czy klucz istnieje,
// trzeba użyć zmiennej typu obiektowego (tutaj Integer, a nie int)
Integer wiek = slownik.get(imie);
if(wiek == null) {
System.out.println("W słowniku nie osoby " + imie);
} else {
System.out.println("Osoba " + imie + " ma " + wiek + " lat");
}
// Można też użyć operacji containsKey do sprawdzenia, czy słownik zawiera podany klucz
// if(slownik.containsKey(imie)) {
// System.out.println("Osoba " + imie + " ma " + slownik.get(imie) + " lat.");
// } else {
// System.out.println("W słowniku nie osoby " + imie);
// }
}
}
}
package gotowe.p25_kolekcje.zbieranie_danych;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class P7_Queue {
// Kolejka to struktura danych zoptymalizowana pod kątem dostępu do "następnego elementu"
// (operacja poll() lub get()).
// * Kolejka prosta (FIFO) zachowuje kolejność elementów i następnym elementem do pobrania jest ten,
// który został najdawniej w kolejce umieszczony.
// Jak "sprawiedliwa" kolejna do kasy w sklepie.
// Najczęściej jest to jednocześnie kolejka dwukońcowa (Dequeue) z możliwością dostepu do obu jej końców.
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Queue<String> kolejka = new LinkedList<>(); // albo ArrayDequeue; - to są "kolejki proste"
System.out.println(kolejka);
System.out.println("Podawaj kolejne elementy, aby dodać do kolejki.\nWpisz '?', aby pobrać element z kolejki, a Enter aby zakończyć program");
while(true) {
System.out.println("Kolejka: " + kolejka);
System.out.print("> ");
String napis = scanner.nextLine();
if(napis.isEmpty()) break;
if(napis.equals("?")) {
String pobrane = kolejka.poll();
System.out.println("Pobrany element: " + pobrane);
} else {
System.out.println("Dodany element: " + napis);
kolejka.add(napis);
}
}
System.out.println("Końcowy rozmiar kolejki " + kolejka.size());
System.out.println(kolejka);
System.out.println("Koniec programu");
}
}
package gotowe.p25_kolekcje.zbieranie_danych;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
public class P8_PriorityQueue {
// * Kolejka priorytetowa może nie zachowywać kolejności (możliwe jest tzw. "zagłodzenie").
// Następnym elementem do pobranie jest element o najwyższym priorytecie
// - w Javie jest to element o najmniejszej wartości (np. napis najwcześniejszy alfabetycznie).
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Queue<String> kolejka = new PriorityQueue<>();
System.out.println(kolejka);
System.out.println("Podawaj kolejne elementy, aby dodać do kolejki.\nWpisz '?', aby pobrać element z kolejki, a Enter aby zakończyć program");
while(true) {
System.out.println("Kolejka: " + kolejka);
System.out.print("> ");
String napis = scanner.nextLine();
if(napis.isEmpty()) break;
if(napis.equals("?")) {
String pobrane = kolejka.poll();
System.out.println("Pobrany element: " + pobrane);
} else {
System.out.println("Dodany element: " + napis);
kolejka.add(napis);
}
}
System.out.println("Końcowy rozmiar kolejki " + kolejka.size());
System.out.println(kolejka);
System.out.println("Koniec programu");
}
}
package gotowe.p31_streamy.c_przeglad_operacji;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import emps.Employee;
import emps.ObslugaCSV;
public class C14_MinMax {
public static void main(String[] args) {
List<Employee> lista = ObslugaCSV.wczytaj();
Optional<Employee> min = lista.stream().min(Comparator.comparing(Employee::getSalary));
Optional<Employee> max = lista.stream().max(Comparator.comparing(Employee::getSalary));
System.out.println("min: " + min);
System.out.println("max: " + max);
System.out.println();
if(min.isPresent()) {
System.out.println("Znaleziono minimum:");
Employee emp = min.get();
System.out.println(emp.getFirstName() + " " + emp.getLastName() + " zarabia " + emp.getSalary());
} else {
System.out.println("nie ma minimum");
}
if(max.isPresent()) {
System.out.println("Znaleziono maximum:");
Employee emp = max.get();
System.out.println(emp.getFirstName() + " " + emp.getLastName() + " zarabia " + emp.getSalary());
} else {
System.out.println("nie ma maximum");
}
System.out.println();
String [] stanowiska = {"Programmer", "Shipping Clerk", "Brygadier"};
for (String stanowisko : stanowiska) {
String tekst = lista.stream()
.filter(emp -> Objects.equals(emp.getJobTitle(), stanowisko))
.max(Comparator.comparing(Employee::getSalary))
.map(emp -> emp.getFirstName() + " " + emp.getLastName() + " zarabia " + emp.getSalary())
.orElse("nie ma takiego gościa");
// powyższe map dotyczy Optional, a nie Stream
System.out.println("Najbogatszy " + stanowisko + ": " + tekst);
}
}
}
package gotowe.p31_streamy.d_redukcje_i_grupowanie;
import java.util.Collection;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import emps.Employee;
import emps.ObslugaCSV;
public class Kolektory1 {
public static void main(String[] args) {
//List<Employee> emps = Collections.emptyList();
List<Employee> emps = ObslugaCSV.wczytaj();
// collectory obliczające standardowe funkcje agregujące
Long ilu = emps.stream().collect(Collectors.counting());
Integer suma = emps.stream().collect(Collectors.summingInt(Employee::getSalary));
Double avg = emps.stream().collect(Collectors.averagingInt(Employee::getSalary));
// dla pustego zbioru danych wychodzi 0.0
System.out.println(ilu + ", " + suma + ", " + avg);
// Porównuje pracowników wg pensji
Comparator<Employee> komp = Comparator.comparingInt(Employee::getSalary);
Optional<Employee> min = emps.stream().collect(Collectors.minBy(komp));
Optional<Employee> max = emps.stream().collect(Collectors.maxBy(komp));
System.out.println(min);
System.out.println(max);
// przykład wyciągaia wartości z Optionala
String str1 = min
.map(emp -> emp.getFirstName()
+ " " + emp.getLastName()
+ " / " + emp.getSalary())
.orElse("nie ma takiego gościa");
System.out.println(str1);
System.out.println();
// Oblicza wszystkie 5 standardowe funkcje agregujące
IntSummaryStatistics statystyki = emps.stream().collect(Collectors.summarizingInt(Employee::getSalary));
System.out.println(statystyki);
System.out.println(statystyki.getAverage());
System.out.println();
// Zestaw kolektorów zbierających dane do kolekcji:
List<String> list1 = emps.stream()
.map(Employee::getFirstName)
.sorted()
.distinct()
.collect(Collectors.toList());
System.out.println(list1);
Set<String> set1 = emps.stream()
.map(Employee::getCity)
.collect(Collectors.toSet());
System.out.println(set1);
Collection<String> kolekcja = emps.stream()
.map(Employee::getCity)
.collect(Collectors.toCollection(TreeSet::new));
System.out.println(kolekcja);
System.out.println();
// Tworząc słownik podajemy skąd się biorą klucze, skąd się biorą wartości
// i ewentualnie jak aktualizować już wpisane wartości
Map<String, Integer> grupy = emps.stream()
.collect(Collectors.toMap(Employee::getCity,
Employee::getSalary,
Math::addExact));
grupy.forEach((k,v) -> System.out.printf("%20s -> %10s\n", k, v));
System.out.println();
String txt1 = emps.stream()
.map(Employee::getDepartmentName)
.distinct()
.collect(Collectors.joining());
System.out.println(txt1);
String txt2 = emps.stream()
.map(Employee::getDepartmentName)
.distinct()
.collect(Collectors.joining(", "));
System.out.println(txt2);
String txt3 = emps.stream()
.map(Employee::getDepartmentName)
.distinct()
.collect(Collectors.joining(", ", "<", ">"));
System.out.println(txt3);
}
}
package gotowe.p31_streamy.d_redukcje_i_grupowanie;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
import emps.Employee;
import emps.ObslugaCSV;
public class Kolektory2 {
public static void main(String[] args) {
//List<Employee> emps = Collections.emptyList();
List<Employee> emps = ObslugaCSV.wczytaj();
// grouping by - zbiera elementy w grupy
Map<String, List<Employee>> grupy1 = emps.stream()
.collect(Collectors.groupingBy(Employee::getJobTitle));
grupy1.forEach((k,v) -> {
System.out.println(k);
v.forEach(emp -> {
System.out.printf(" %-12s %-12s %10s\n", emp.getFirstName(), emp.getLastName(), emp.getSalary());
});
});
System.out.println();
// Podajemy dodatkowy kolektor mówiący co robić z każdą grupą
Map<String, Integer> grupy2 = emps.stream()
.collect(Collectors.groupingBy(
Employee::getJobTitle,
Collectors.summingInt(Employee::getSalary)));
grupy2.forEach((k,v) -> {
System.out.printf("%-32s %12s\n", k, v);
});
System.out.println();
// Możemy też podać fabrykę map jako środkowy parametr
Map<String, Integer> grupy3 = emps.stream()
.collect(Collectors.groupingBy(
Employee::getJobTitle,
TreeMap::new,
Collectors.summingInt(Employee::getSalary)));
grupy3.forEach((k,v) -> {
System.out.printf("%-32s %12s\n", k, v);
});
System.out.println();
System.out.println("================");
Map<Boolean, List<Employee>> partycje1 = emps.stream()
.collect(Collectors.partitioningBy(emp -> emp.getSalary() >= 10000));
System.out.println("Bogaci:");
partycje1.get(true)
.forEach(emp -> System.out.println(" " + emp.getLastName()));
System.out.println("\nBiedni:");
partycje1.get(false)
.forEach(emp -> System.out.println(" "+ emp.getLastName()));
System.out.println();
Map<Boolean, Long> partycje2 = emps.stream()
.collect(Collectors.partitioningBy(
emp -> emp.getSalary() >= 10000,
Collectors.counting()));
System.out.println("Bogatych " + partycje2.get(true));
System.out.println("Biednych " + partycje2.get(false));
}
}
package gotowe.p31_streamy.e_parallel;
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> ("Hello, Async!"))
.thenApply(String::toUpperCase)
.thenAccept(System.out::println)
;
System.out.println("Koniec main");
}
}
\ No newline at end of file
package gotowe.p31_streamy.e_parallel;
import java.util.concurrent.CompletableFuture;
public class CompletableFutureMonadExample {
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, Monads!")
.thenApply(String::toUpperCase) // Zmiana na wielkie litery
.thenApply(result -> result + " with CompletableFuture");
future.thenAccept(System.out::println); // Wyświetlenie wyniku
}
}
\ No newline at end of file
package gotowe.p31_streamy.e_parallel;
public class IleMamProckow {
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
System.out.println("procki " + runtime.availableProcessors());
System.out.println("zajęta pamięć: " + (runtime.totalMemory() - runtime.freeMemory()));
}
}
package gotowe.p32_spliterator;
import java.util.List;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class SlidingWindowSpliterator<T> implements Spliterator<List<T>> {
private final List<T> list;
private final int windowSize;
private int currentIndex = 0;
public SlidingWindowSpliterator(List<T> list, int windowSize) {
this.list = list;
this.windowSize = windowSize;
}
@Override
public boolean tryAdvance(Consumer<? super List<T>> action) {
if (currentIndex + windowSize <= list.size()) {
List<T> window = list.subList(currentIndex, currentIndex + windowSize);
action.accept(window);
currentIndex++;
return true;
}
return false;
}
@Override
public Spliterator<List<T>> trySplit() {
return null; // Prosta implementacja, brak podziału
}
@Override
public long estimateSize() {
return list.size() - windowSize + 1L;
}
@Override
public int characteristics() {
return ORDERED | NONNULL | SIZED;
}
public static <T> Stream<List<T>> slidingWindowStream(List<T> list, int windowSize) {
return StreamSupport.stream(new SlidingWindowSpliterator<>(list, windowSize), false);
}
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
SlidingWindowSpliterator.slidingWindowStream(numbers, 3)
.forEach(System.out::println);
// Wynik:
// [1, 2, 3]
// [2, 3, 4]
// [3, 4, 5]
}
}
\ No newline at end of file
......@@ -51,7 +51,7 @@ public class KlasaOptional {
}
System.out.println();
// Można też pobierając wartość zastąpić ją wartością domyślną w przypadku braku danych:
// Można też pobierając wartość zastąpić ją wartością domyślną w przypadku braku danych:
for(Optional<String> opt : lista) {
String napis = opt.orElse("nieznana osoba");
System.out.println("Witaj osobo " + napis);
......
package gotowe.p48_xml;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
public class Transformacja1 {
public static void main(String[] args) {
File plik = new File("pliki/sklep.xml");
File xsl = new File("pliki/sklep_html.xsl");
File out = new File("out/sklep.html");
System.out.println("Startujemy");
try {
long t1 = System.nanoTime();
TransformerFactory tf = TransformerFactory.newInstance();
// domyślny transformer nie zmienia zawartości,
// ale za jego pomocą można zmienić "wewn ętrzny format",
// np. z drzewa DOM zrobić strumień SAX itp.
// Transformer transformer = tf.newTransformer();
// tutaj tworzymy Transformer na podstawie arkusza XSLT:
// Platforma Java ma wbudowaną obsługę XSLT v 1.0,
// Biblioteka Saxon pozwala obsłużyć także XSLT 2.0, 3.1, XQuery
Transformer transformer = tf.newTransformer(new StreamSource(xsl));
transformer.transform(new StreamSource(plik), new StreamResult(out));
System.out.println("Gotowe");
long t3 = System.nanoTime();
Runtime runtime = Runtime.getRuntime();
System.out.printf("Czas łączny : %.6f s%n", (t3-t1) * 1e-9);
System.out.printf("Zajęta pamięć : %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.gc();
Thread.sleep(1000);
System.out.printf("Zajęta pamięć po gc: %,d B%n", runtime.totalMemory() - runtime.freeMemory());
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.p48_xml;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
public class Transformacja2 {
public static void main(String[] args) {
File plik = new File("pliki/sklep.xml");
File xsl = new File("pliki/sklep_filtr.xsl");
File out = new File("out/sklep_przefiltrowany.xml");
System.out.println("Startujemy");
try {
long t1 = System.nanoTime();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer(new StreamSource(xsl));
transformer.setParameter("kategoria", "herbata");
transformer.transform(new StreamSource(plik), new StreamResult(out));
System.out.println("Gotowe");
long t3 = System.nanoTime();
Runtime runtime = Runtime.getRuntime();
System.out.printf("Czas łączny : %.6f s%n", (t3-t1) * 1e-9);
System.out.printf("Zajęta pamięć : %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.gc();
Thread.sleep(1000);
System.out.printf("Zajęta pamięć po gc: %,d B%n", runtime.totalMemory() - runtime.freeMemory());
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.p48_xml;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import java.io.File;
public class Walidacja {
public static void main(String[] args) {
try {
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("pliki/sklep.xsd"));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setSchema(schema);
// gdybyśmy nie podali error handlera, to warning oraz error wypisuje teksty na stderr
// a fatalError przerywa program; przy czym typowe błędy walidacji są zgłaszane jako 'error'
// my jednak użyjemy własnego error handlera:
MojErrorHandler errorHandler = new MojErrorHandler();
DocumentBuilder builder = dbf.newDocumentBuilder();
builder.setErrorHandler(errorHandler);
Document doc = builder.parse("pliki/sklep.xml");
System.out.println("Dokument wczytany " + doc);
if(errorHandler.bylyBledy()) {
System.out.println("Było " + errorHandler.getLicznikBledow() + " błędów");
}
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
String nazwa = xpath.evaluate("//towar[3]/nazwa", doc);
System.out.println("Nazwa towaru: " + nazwa);
} catch (Exception e) {
e.printStackTrace();
}
}
private static class MojErrorHandler implements ErrorHandler {
private int licznikBledow = 0;
@Override
public void warning(SAXParseException exception) throws SAXException {
System.err.println(exception.getMessage());
}
@Override
public void error(SAXParseException exception) throws SAXException {
licznikBledow++;
System.err.println(exception.getMessage());
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
System.err.println(exception.getMessage());
throw exception;
}
public int getLicznikBledow() {
return licznikBledow;
}
public boolean bylyBledy() {
return licznikBledow > 0;
}
}
}
package gotowe.p48_xml;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
public class Waluty1_Dom {
public static void main(String[] args) {
File plik = new File("pliki/waluty2023.xml");
String waluta = "EUR";
System.out.println("Startujemy");
long t1 = System.nanoTime();
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(plik);
long t2 = System.nanoTime();
double min = Double.MAX_VALUE, max = 0, sum = 0;
int count = 0;
NodeList tables = doc.getElementsByTagName("ExchangeRatesTable");
final int n = tables.getLength();
for(int i = 0; i < n; i++) {
Element table = (Element) tables.item(i);
// ryzyko NPE, gdyby plik był niepoprawny:
String effectiveDate = table.getElementsByTagName("EffectiveDate").item(0).getTextContent();
// System.out.println(effectiveDate);
NodeList rates = table.getElementsByTagName("Rate");
final int m = rates.getLength();
for(int j = 0; j < m; j++) {
Element rate = (Element) rates.item(j);
String code = rate.getElementsByTagName("Code").item(0).getTextContent();
if(code.equals(waluta)) {
double mid = Double.parseDouble(rate.getElementsByTagName("Mid").item(0).getTextContent());
count++;
sum += mid;
if(mid < min) min = mid;
if(mid > max) max = mid;
}
}
}
long t3 = System.nanoTime();
Runtime runtime = Runtime.getRuntime();
System.out.printf("Czas czytania pliku: %.6f s%n", (t2-t1) * 1e-9);
System.out.printf("Czas liczenia : %.6f s%n", (t3-t2) * 1e-9);
System.out.printf("Czas łączny : %.6f s%n", (t3-t1) * 1e-9);
System.out.printf("Zajęta pamięć : %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.gc();
Thread.sleep(1000);
System.out.printf("Zajęta pamięć po gc: %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.out.println("Count: " + count);
if(count > 0) {
System.out.println("Avg: " + (sum / count));
System.out.println("Min: " + min);
System.out.println("Max: " + max);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.p48_xml;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.File;
public class Waluty2_XPath {
// Wersja w swojej strukturze podobna do Waluty1_Dom, ale zamiast getElementsByTagName będziemy tu używać wyrażeń XPath
public static void main(String[] args) {
File plik = new File("pliki/waluty2023.xml");
String waluta = "EUR";
System.out.println("Startujemy");
long t1 = System.nanoTime();
try {
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(plik);
long t2 = System.nanoTime();
double min = Double.MAX_VALUE, max = 0, sum = 0;
int count = 0;
NodeList tables = (NodeList) xpath.evaluate("//ExchangeRatesTable", doc, XPathConstants.NODESET);
final int n = tables.getLength();
for(int i = 0; i < n; i++) {
Node table = tables.item(i);
String effectiveDate = xpath.evaluate("EffectiveDate", table);
// System.out.println(effectiveDate);
NodeList rates = (NodeList) xpath.evaluate("Rates/Rate[Code='" + waluta + "']", table, XPathConstants.NODESET);
final int m = rates.getLength();
for(int j = 0; j < m; j++) {
Node rate = rates.item(j);
double mid = (Double) xpath.evaluate("Mid", rate, XPathConstants.NUMBER);
count++;
sum += mid;
if(mid < min) min = mid;
if(mid > max) max = mid;
}
}
long t3 = System.nanoTime();
Runtime runtime = Runtime.getRuntime();
System.out.printf("Czas czytania pliku: %.6f s%n", (t2-t1) * 1e-9);
System.out.printf("Czas liczenia : %.6f s%n", (t3-t2) * 1e-9);
System.out.printf("Czas łączny : %.6f s%n", (t3-t1) * 1e-9);
System.out.printf("Zajęta pamięć : %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.gc();
Thread.sleep(1000);
System.out.printf("Zajęta pamięć po gc: %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.out.println("Count: " + count);
if(count > 0) {
System.out.println("Sum: " + sum);
System.out.println("Avg: " + (sum / count));
System.out.println("Min: " + min);
System.out.println("Max: " + max);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.p48_xml;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.File;
public class Waluty3_XPath {
// W tej wersji staram się od razu jak najwięcej wyrazić w języku XPath, a jak najmiej pisać w Javie.
public static void main(String[] args) {
String plik = "pliki/waluty2023.xml";
String waluta = "EUR";
System.out.println("Startujemy");
long t1 = System.nanoTime();
try {
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
XPathExpression kropka = xpath.compile(".");
InputSource src = new InputSource(plik);
long t2 = System.nanoTime();
double min = Double.MAX_VALUE, max = 0, sum = 0;
waluta = waluta.replace("'", "''"); // eskejpowanie dla bezpieczeństwa
final String expr = "/ArrayOfExchangeRatesTable/ExchangeRatesTable/Rates/Rate[Code='" + waluta + "']/Mid";
NodeList mids = (NodeList) xpath.evaluate(expr, src, XPathConstants.NODESET);
final int count = mids.getLength();
for(int i = 0; i < count; i++) {
double mid = (Double) kropka.evaluate(mids.item(i), XPathConstants.NUMBER);
sum += mid;
if(mid < min) min = mid;
if(mid > max) max = mid;
}
long t3 = System.nanoTime();
Runtime runtime = Runtime.getRuntime();
System.out.printf("Czas łączny : %.6f s%n", (t3-t1) * 1e-9);
System.out.printf("Zajęta pamięć : %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.gc();
Thread.sleep(1000);
System.out.printf("Zajęta pamięć po gc: %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.out.println("Count: " + count);
if(count > 0) {
System.out.println("Sum: " + sum);
System.out.println("Avg: " + (sum / count));
System.out.println("Min: " + min);
System.out.println("Max: " + max);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.p48_xml;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.FileInputStream;
public class Waluty3a_XPath_TylkoSuma {
// W tej wersji staram się od razu jak najwięcej wyrazić w języku XPath, a jak najmiej pisać w Javie.
public static void main(String[] args) {
String plik = "pliki/waluty2023.xml";
String waluta = "EUR";
System.out.println("Startujemy");
long t1 = System.nanoTime();
try {
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
InputSource src = new InputSource(plik);
long t2 = System.nanoTime();
waluta = waluta.replace("'", "''"); // eskejpowanie dla bezpieczeństwa
final String expr = "sum(/ArrayOfExchangeRatesTable/ExchangeRatesTable/Rates/Rate[Code='" + waluta + "']/Mid)";
double sum = (Double)xpath.evaluate(expr, src, XPathConstants.NUMBER);
long t3 = System.nanoTime();
Runtime runtime = Runtime.getRuntime();
System.out.printf("Czas czytania pliku: %.6f s%n", (t2-t1) * 1e-9);
System.out.printf("Czas liczenia : %.6f s%n", (t3-t2) * 1e-9);
System.out.printf("Czas łączny : %.6f s%n", (t3-t1) * 1e-9);
System.out.printf("Zajęta pamięć : %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.gc();
Thread.sleep(1000);
System.out.printf("Zajęta pamięć po gc: %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.out.println("Sum: " + sum);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.p48_xml;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.XMLEvent;
import java.io.FileReader;
/* Wersja oparta o StAX EventReader - dokument nie jest wczytywany do pamięci "na raz",
ale w każdym kroku tworzony jest (zwykle b. mały) obiekt Event (różnego typu),
co powoduje, że wydajność nie jest jeszcze optymalna,
ale za to programuje się nieco wygodniej, niż w następnej wersji.
*/
public class Waluty4_StaxEvent {
public static void main(String[] args) {
String plik = "pliki/waluty2023.xml";
String waluta = "EUR";
System.out.println("Startujemy");
long t1 = System.nanoTime();
try {
XMLInputFactory xif = XMLInputFactory.newDefaultFactory();
XMLEventReader reader = xif.createXMLEventReader(new FileReader(plik));
double min = Double.MAX_VALUE, max = 0, sum = 0;
int count = 0;
while(reader.hasNext()) {
XMLEvent event = reader.nextEvent();
if(event.isStartElement() && event.asStartElement().getName().getLocalPart().equals("Rate")) {
boolean uwzgledniajWalute = false;
while(true) {
XMLEvent event2 = reader.nextEvent();
if(event2.isStartElement() && event2.asStartElement().getName().getLocalPart().equals("Code")) {
if(waluta.equals(reader.getElementText())) {
uwzgledniajWalute = true;
}
} else
if(event2.isStartElement() && event2.asStartElement().getName().getLocalPart().equals("Mid")) {
if(uwzgledniajWalute) {
double mid = Double.parseDouble(reader.getElementText());
count++;
sum += mid;
if(mid < min) min = mid;
if(mid > max) max = mid;
}
} else
if(event2.isEndElement() && event2.asEndElement().getName().getLocalPart().equals("Rate")) {
break;
}
}
}
}
long t3 = System.nanoTime();
Runtime runtime = Runtime.getRuntime();
System.out.printf("Czas łączny : %.6f s%n", (t3-t1) * 1e-9);
System.out.printf("Zajęta pamięć : %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.gc();
Thread.sleep(1000);
System.out.printf("Zajęta pamięć po gc: %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.out.println("Count: " + count);
if(count > 0) {
System.out.println("Sum: " + sum);
System.out.println("Avg: " + (sum / count));
System.out.println("Min: " + min);
System.out.println("Max: " + max);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.p48_xml;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLInputFactory;
import java.io.FileReader;
/* Wersja oparta o StAX StreamReader - w tym rozwiązaniu nie są tworzone obiekty Event dla każdego kroku,
dzięki czemu jest to bardziej wydajne (gł pamięciowo), niż wersja poprzednia.
*/
public class Waluty5_StaxStream {
public static void main(String[] args) {
String plik = "pliki/waluty2023.xml";
String waluta = "EUR";
System.out.println("Startujemy");
long t1 = System.nanoTime();
try {
XMLInputFactory xif = XMLInputFactory.newDefaultFactory();
XMLStreamReader reader = xif.createXMLStreamReader(new FileReader(plik));
double min = Double.MAX_VALUE, max = 0, sum = 0;
int count = 0;
while(reader.hasNext()) {
int event = reader.next();
if(event == XMLStreamReader.START_ELEMENT && reader.getName().getLocalPart().equals("Rate")) {
boolean uwzgledniajWalute = false;
while(true) {
reader.next();
if(reader.isStartElement() && reader.getName().getLocalPart().equals("Code")) {
if(waluta.equals(reader.getElementText())) {
uwzgledniajWalute = true;
}
} else
if(reader.isStartElement() && reader.getName().getLocalPart().equals("Mid")) {
if(uwzgledniajWalute) {
double mid = Double.parseDouble(reader.getElementText());
count++;
sum += mid;
if(mid < min) min = mid;
if(mid > max) max = mid;
}
} else
if(reader.isEndElement() && reader.getName().getLocalPart().equals("Rate")) {
break;
}
}
}
}
long t3 = System.nanoTime();
Runtime runtime = Runtime.getRuntime();
System.out.printf("Czas łączny : %.6f s%n", (t3-t1) * 1e-9);
System.out.printf("Zajęta pamięć : %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.gc();
Thread.sleep(1000);
System.out.printf("Zajęta pamięć po gc: %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.out.println("Count: " + count);
if(count > 0) {
System.out.println("Sum: " + sum);
System.out.println("Avg: " + (sum / count));
System.out.println("Min: " + min);
System.out.println("Max: " + max);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package gotowe.p48_xml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
public class Waluty6_Sax {
public static void main(String[] args) {
File plik = new File("pliki/waluty2023.xml");
String szukanaWaluta = "EUR";
try {
System.out.println("Startujemy");
long t1 = System.nanoTime();
WalutyHandler handler = new WalutyHandler(szukanaWaluta);
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
SAXParser parser = factory.newSAXParser();
parser.parse(plik, handler);
long t3 = System.nanoTime();
Runtime runtime = Runtime.getRuntime();
System.out.printf("Czas łączny : %.6f s%n", (t3-t1) * 1e-9);
System.out.printf("Zajęta pamięć : %,d B%n", runtime.totalMemory() - runtime.freeMemory());
System.gc();
Thread.sleep(1000);
System.out.printf("Zajęta pamięć po gc: %,d B%n", runtime.totalMemory() - runtime.freeMemory());
handler.printResults();
} catch (Exception e) {
e.printStackTrace();
}
}
private static enum Stan {
DOMYSLNY,
/** znajduję się wewnątrz elementu Code i odczytuję tekstowy kod waluty */
CODE,
/** znajduję się wewnątrz Rate i wiem, że mam do czynienia z szukaną walutą */
NASZA_WALUTA,
/** znajduję się wewnątrz elementu Mid szukanej waluty */
MID,
}
private static class WalutyHandler extends DefaultHandler {
private final String szukanaWaluta;
private Stan stan = Stan.DOMYSLNY;
private StringBuilder buf = null;
private int count = 0;
private double sum = 0, min = Double.MAX_VALUE, max = Double.MIN_VALUE;
public WalutyHandler(String szukanaWaluta) {
this.szukanaWaluta = szukanaWaluta;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if("Code".equals(localName)) {
// musimy sprawdzić, czy nazwa waluty się zgadza
// ale w SAX nie ma możliwości odczytania zawartości tekstowej, gdy znajdujemy się w początku elementu,
// trzeba to zrobić w metodzie characters
stan = Stan.CODE;
buf = new StringBuilder();
} else if("Mid".equals(localName) && stan == Stan.NASZA_WALUTA) {
stan = Stan.MID;
buf = new StringBuilder();
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if(stan == Stan.CODE) {
if(szukanaWaluta.contentEquals(buf)) {
stan = Stan.NASZA_WALUTA;
} else {
stan = Stan.DOMYSLNY;
}
buf = null;
} else if(stan == Stan.MID) {
double mid = Double.parseDouble(buf.toString());
count++;
sum += mid;
if(mid < min) min = mid;
if(mid > max) max = mid;
buf = null;
stan = Stan.DOMYSLNY;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
/* Ponieważ w ogólności parsery SAX mają prawo podzielić węzeł tekstowy na części
i wywołać wiele razy characters dla jednego węzeła tekstowego,
to musimy fragmenty tekstu "skleić" za pomocą StringBuilder.
Dopiero w metodzie endElement wiemy, że tekst się skończył i tam z niego skorzystamy.
*/
if(stan == Stan.CODE || stan == Stan.MID) {
buf.append(ch, start, length);
}
}
public int getCount() {
return count;
}
public double getSum() {
return sum;
}
public double getMin() {
return min;
}
public double getMax() {
return max;
}
public double getAverage() {
return sum / count;
}
public String getSzukanaWaluta() {
return szukanaWaluta;
}
public void printResults() {
System.out.println("Count: " + count);
if(count > 0) {
System.out.println("Avg: " + getAverage());
System.out.println("Min: " + min);
System.out.println("Max: " + max);
}
}
}
}
package gotowe.p48_xml;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.util.Optional;
public class WypiszOsobyDom {
public static void main(String[] args) {
System.out.println("Startujemy");
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// dbf.setIgnoringComments(true);
// dbf.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse("pliki/osoby.xml");
System.out.println("Dokument wczytany " + doc);
Element osoby = doc.getDocumentElement();
System.out.println(osoby);
// Jesteśmy w węźle <osoby>, a tak możemy przejść do jego "dzieci", czyli <osoba>
// Sposób pierwszy: pętla po wszystkich dzieciach. Ale to obejmie również węzły tekstowe, komentarze itp.
for(Node node = osoby.getFirstChild(); node != null; node = node.getNextSibling()) {
System.out.println(node);
}
System.out.println("=========");
// Jeśli jednak spodziewamy się elementów o określonej nazwie i chcemy od razu do nich przejść,
// łatwiej będzie użyć drugiego sposobu:
NodeList nodeSetOsoba = osoby.getElementsByTagName("osoba");
for(int i = 0 ; i < nodeSetOsoba.getLength(); i++) {
Element osoba = (Element)nodeSetOsoba.item(i);
// String imie = osoba.getElementsByTagName("imie").item(0).getTextContent();
// Aby w razie braku elementu imie uzyskać pusty string, można np tak wykorzystać klasę Optional
String imie = Optional.ofNullable(osoba.getElementsByTagName("imie").item(0)).map(Node::getTextContent).orElse("");
String nazwisko = Optional.ofNullable(osoba.getElementsByTagName("nazwisko").item(0)).map(Node::getTextContent).orElse("");
String data = Optional.ofNullable(osoba.getElementsByTagName("dataUrodzenia").item(0)).map(Node::getTextContent).orElse("");
String plec = osoba.getAttribute("plec");
System.out.println("Osoba " + imie + " " + nazwisko + ", ur. " + data + " płeć: " + plec);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment