Sunday, May 5, 2013

MySQL'de XML ile Çalışmak

MySQL ilişkisel veritabanı yönetim sisteminde XML veriler ile çalışmak mümkündür. İlk olarak sorgu sonuçlarını nasıl XML olarak alabileceğimizi görelim:

$ mysql -uroot -proot world --xml -e "select * from Country where continent='Asia'" 
<?xml version="1.0"?>

<resultset statement="select * from Country where continent='Asia'
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <row>
        <field name="Code">AFG</field>
        <field name="Name">Afghanistan</field>
        <field name="Continent">Asia</field>
        <field name="Region">Southern and Central Asia</field>
        <field name="SurfaceArea">652090.00</field>
        <field name="IndepYear">1919</field>
        <field name="Population">22720000</field>
        <field name="LifeExpectancy">45.9</field>
        <field name="GNP">5976.00</field>
        <field name="GNPOld" xsi:nil="true" />
        <field name="LocalName">Afganistan/Afqanestan</field>
        <field name="GovernmentForm">Islamic Emirate</field>
        <field name="HeadOfState">Mohammad Omar</field>
        <field name="Capital">1</field>
        <field name="Code2">AF</field>
  </row>
  .
  .
  .
Burada -e ile mysqld sunucusundan select * from Country where continent='Asia' sorgusunu çalıştırmasını, --xml ile sorgu cevabını XML belgesi olarak ekrana dökmesini istiyoruz. İsterseniz sorgu sonucunu --html seçeneğini vererek doğrudan HTML belgesi olarak da alabilirsiniz. 
Burada mysqld sunucusunun döndürdüğü XML'i daha zengin bir içeriğe dönüştürmek üzere aşağıdaki XSL dönüşümünü uygulayabiliriz:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml"/>
    <xsl:template match="/resultset">
        <countries>
            <xsl:for-each select="row">
                <country>
                    <xsl:for-each select="field">
                        <xsl:element name="{@name}" >
                            <xsl:value-of select="."/>
                        </xsl:element>
                    </xsl:for-each>
                </country>
            </xsl:for-each>
        </countries>
    </xsl:template>
</xsl:stylesheet>

Dönüşüm sonunda Asya ülkelerinin listesini yine XML belgesi olarak elde ediyoruz:

<?xml version="1.0" encoding="UTF-8"?>
<countries>        
    <country>
        <Code>AFG</Code>
        <Name>Afghanistan</Name>
        <Continent>Asia</Continent>
        <Region>Southern and Central Asia</Region>
        <SurfaceArea>652090.00</SurfaceArea>
        <IndepYear>1919</IndepYear>
        <Population>22720000</Population>
        <LifeExpectancy>45.9</LifeExpectancy>
        <GNP>5976.00</GNP>
        <GNPOld/>
        <LocalName>Afganistan/Afqanestan</LocalName>
        <GovernmentForm>Islamic Emirate</GovernmentForm>
        <HeadOfState>Mohammad Omar</HeadOfState>
        <Capital>1</Capital>
        <Code2>AF</Code2>
    </country>
.
.
.
XML bir dokümanı herhangi bir tablonun bir sütununda saklayabilirsiniz. Bunun için o sütunu TEXT tiplerinden birini kullanarak tanımlamanız gerekir:
mysql> use test
Database changed
mysql> create table continents (
    -> name varchar(64) not null,
    -> countries MEDIUMTEXT not null ) ;
Query OK, 0 rows affected (0.35 sec)
XML dosyayı bir değişkene okuyabilirsiniz:
mysql> SET @xml = LOAD_FILE("c:\\temp\\asia.xml");
Query OK, 0 rows affected (0.10 sec)
Bundan sonra tabloya eklemek için INSERT INTO cümlesi çalıştırmak yeterli olacaktır:
mysql> insert into continents values ('Asia',@xml);
Query OK, 1 row affected (0.10 sec)
XML dokümanı sakladığınız sütunu sorgularda kullanabilir ve sonucu bir değişkene alabilirsiniz:
mysql> SELECT countries FROM continents where name='Asia' INTO @xml;
Query OK, 1 row affected (0.04 sec)
MySQL XML dokümanlardan üzerinde XPath ifadeleri çalıştırabilmek için ExtractValue isimli bir fonksiyon sağlıyor. Kullanımına ilişkin bir kaç örneği aşağıda bulabilirsiniz: 
  • Asya ülkelerinin sayısını öğrenmek için count(//row) XPath ifadesini kullanabiliriz:
mysql> SELECT ExtractValue(@xml, 'count(//row)');
+------------------------------------+
| ExtractValue(@xml, 'count(//row)') |
+------------------------------------+
| 51                                 |
+------------------------------------+
1 row in set (0.00 sec)
  • Asya ülkelerinin toplam nüfusunu elde etmek için
mysql> SELECT ExtractValue(@xml, "sum(//row/field[@name='Population'])") as 'Tot
al Population';
+------------------+
| Total Population |
+------------------+
| 3705025700       |
+------------------+
1 row in set (0.00 sec)
ExtractValue ve XPath ile birlikte kullanımına ilişkin daha fazla detayı bu bağlantıdan öğrenebilirsiniz.


No comments:

Post a Comment