14 Temmuz 2015 Salı

XML ve DOM

DOM Nedir?
XML (Extensible Markup Language) içinde language kelimesini barındırdığı için sanki bir programlama diliymiş gibi algılanıyor. XML bir programlama dili değil, bir veri formatı. Verinin bilgisayar belleğinde saklanma ve erişilme yöntemlerinden birisi Document Object Model yani DOM.

DOM W3C tarafından yayınlanan bir standart. Bir çok kütüphane programlama dili DOM ile çalışabilmek için sınıflar sunuyor. DOM programlama dilinden bağımsız bir tanımlama sunuyor

The Document Object Model (DOM) is a cross-platform and language-independent convention for representing and interacting with objects in HTML, XHTML and XML documents.
Bu tanımlama IDL ile yapılmış.
In order to provide a precise, language-independent specification of the DOM interfaces, we have chosen to define the specifications in OMG IDL
Diğer Seçenekler
DOM XML ile çalışmak için tek yöntem değil. 
  • XML kullanırken SAX ve diğer XML parser'larını kullanabiliriz.  XML ve SAX başlıklı yazıya göz atabilirsiniz.
  • Java, C# gibi dillerde mevcut olan Serialization sınıflarını tercih edebiliriz. Serialization sınıflarını kullanması çok daha kolay.
Object Oriented View ve Flat View
DOM standardında iki yöntem var. Geleneksel arayüz hiyerarşisi ve daha sade Node arayüzü. Node arayüzü performansın önemli olduğu durumlarda bir sürü cast işlemi yapmamak için kullanılır. Node arayüzündeki nodeName ile Event arayüzündeki tagName aynı şeylerdir.

Node arayüzündeki nodeName, nodeValue, attributes gibi alanlar olsa da tüm Node'dan kalıtan arayüzlerde bunlar desteklenmeyebilir. Örneğin Comment düğümünün attribute listesi olamaz.

DOM Yardımcı Arayüzleri
NodeList : sıralamayı esas alır.
NamedNodeMap : Düğümlere isimle erişim sağlar ama sıralamayı dikkate almaz.

Temel DOM Tipleri
DOMString : 2 byte'lık UTF-16 karakter dizisi. Java'daki string ile aynıdır.
DOMTimeStamp : Milisaniye cinsindendir.

DOM Node Tipleri Nelerdir?
Dom ile node'lar çeşitli tiplere ayrılıyorlar. Bunlar:
  • Document, 
  • DocumentFragment, 
  • DocumentType, 
  • EntityReference, 
  • Element, 
  • Attr, 
  • ProcessingInstruction, 
  • Comment, 
  • Text, 
  • CDATASection, 
  • Entity, 
  • Notation
Node yani düğüm genellikle ata sınıf olarak kullanılıyor.

Document
Kök düğüm anlamına gelir.

Element 
tag ve arasındaki her şey anlamına gelir.

Element örneği :
<a>Some text</a>

Element ve attribute örneği:
<a id="7">Some text</a>

İç içe element örneği
<main att="123">SomeText
    <child>sample</child>
</main>
Göze biraz tuhaf görünse de bu örnek well-defined.

CData
Tag içindeki serbest metin gibidir. Parser tarafından parse edilmez.
<div>This CDATA is a child of the div element.</div>

Bu nodelar dışında her kütüphane veya programlama dili kendince isimlendirdiği sınıflar sunuyor.

Önemli DOM metodları
document.getElementById ()
document.getElementsByTagName()
 
QT
QDomDocument QDomNodeList QDomElement sınıfları XML ile çalışmak için temel sınırlar. Örnek'te bir XML tag'inin attribute değeri güncelleniyor ve XML tekrar kaydediliyor.
// Open file
QDomDocument doc("mydocument");
QFile file("mydocument.xml");
if (!file.open(QIODevice::ReadOnly)) {
    qError("Cannot open the file");
    return;
}
// Parse file
if (!doc.setContent(&file)) {
   qError("Cannot parse the content");
   file.close();
   return;
}
file.close();

// Modify content
QDomNodeList roots = elementsByTagName("root");
if (roots.size() < 1) {
   qError("Cannot find root");
   return;
}
QDomElement root = roots.at(0).toElement();
root.setAttribute("rootname", "RN");
// Then do the same thing for somechild
...

// Save content back to the file
if (!file.open(QIODevice::Truncate | QIODevice::WriteOnly)) {
    qError("Basically, now we lost content of a file");
    return;
}
QByteArray xml = doc.toByteArray();
file.write(xml);
file.close();
Java
DocumentBuilderFactory
newInstance
Sınıfın kendi kendini yaratması için kullanılır.

setValidating
XML dosyasının bir XSD kullanılarak doğrulanmasını sağlar. Örnek:
public boolean validate() {
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

  factory.setValidating(true);

  factory.setAttribute(
        "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
        "http://www.w3.org/2001/XMLSchema");
  factory.setAttribute(
        "http://java.sun.com/xml/jaxp/properties/schemaSource",
        "http://domain.com/mynamespace/mySchema.xsd");
  Document doc = null;
  try {
    DocumentBuilder parser = factory.newDocumentBuilder();
    doc = parser.parse("data.xml");
    return true;
  } catch (Exception e) {
    return false;
  }
}
 
DocumentBuilder
Bu sınıfa niçin "Builder" demişler ben de bilmiyorum. İçine çok fazla sayıda parametre alan başka bir sınıfı kolayca ilklendirmemize yarayan Builder örüntüsü ile alakası bence yok. Document nesnesine atanabilecek çok fazla parametre görmüyorum.
newDocument
Bu metodu ile boş bir Document sınıfı yaratılır.
// Step 1: create a DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// Step 2: create a DocumentBuilder
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc =documentBuilder.newDocument();
parse 
Herhangi bir input stream yüklenebilir.
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document dDoc = builder.parse(con.getInputStream());
setErrorHandler
DocumentBuilder'a istenirse dışarıdan bir ErrorHandler sınıfı atanabilir. Örneği buradan aldım.

Document
getAttributes
Bu metod ile xml'in attribute map'i alınır. Örnek:
String oldDate =nodes.item(i).getAttributes().getNamedItem("doj").getNodeValue();
 
getDocumentElement
Dokümanın ilk root xml elemanını verir. Comment gibi node'lar varsa bunları atlar. Aşağıdaki örnekte hemen catalog olan node'u verir.
<?xml version="1.0"?>
<!-- Edited by XMLSpy -->
<catalog>
   
</catalog>
 
getElementsByTagName
Bu metod ile verilen isme sahip tüm elementler XML dokümanının neresinde olursa olsun döndürülür. Örnek:

Bu XML dokümanı için getElementsByTagName("link"); metodu 2 tane sonuç döndürür.

getFirstChild
Bir node'un ilk alt elemanını döndürür. Aşağıdaki örnekte bir node'un tüm ilk seviye alt elemanlarını dolaşmak için kod var.
for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {}

NodeList  
Nodelara index numarası ile erişebildiğimiz bir liste
getLength() ve item() diye iki metodu bulunur. Örnek:
NodeList nodes = doc.getElementsByTagName("empDetails");
for (int i = 0; i < nodes.getLength(); i++){
 Node node = nodes.item (i);
}

NamedNodeMap
Node'lara isimle veya indeks numarası ile erişebildiğimiz bir map.
getNamedItem
Örnek:
String oldDate =nodes.item(i).getAttributes().getNamedItem("doj").getNodeValue();
Element
getAttribute
Bu metod ile node ile element'in temel farkı olan attribute alanının değeri alınır.

elementleri bulmak
DOM içindeki Element sınıflarını dolaşmak için aşağıdaki gibi yapılabilir.

Document doc;
NoteList nodelist = doc.getElementsByTagName ("record");
for (int index = 0;index < nodeList.getLength (); index++){
 Node record = nodeList.item (index);
 if (record.getNodeType () == Node.ELEMENT_NODE){
  Element element = (Element)record;
 }
}  

SchemaFactory 
Scheme ve Validator Sınıfları yazısına taşıdım.


Transformer
newTransformer - xsl ile dönüştürmek
Aşağıdaki örnekte xsl ile verilen xml bir başka xml'e dönüştürülüyor.

//Source xml
Source source = new DOMSource(dataDoc);
//Target xml
Result result = new StreamResult(new File("output.xml"));

//Create transformer
Source xsl = new StreamSource("newstylesheet1.xsl");
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(xsl);

//Transform
transformer.transform(source, result);
newTransformer - Değiştirilen Document Nesnesini Kaydetmek
Aşağıdaki örnekte ise verilen string Document olarak parse edildikten sonra Transformer aracılığıyla xml dosyasına kaydediliyor.
 
C#
XMLDocument
DocumentElement
Root elementi verir. Aşağıdaki XML'de tokens ile başlayan element'e denk gelir.
<?xml version="1.0" encoding="utf-8" ?>
<tokens>
    <token id="1"/>
    <token id="2"/>
</tokens>
 
XmlDocument document = new XMLDocument()
document.Load("Token.xml");
foreach (XmlNode node in document.DocumentElement.ChildNodes)
{
 out.Writeln (node["id"].InnerText);
}


GetElementsByTagName metodu
Örnek:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(sampleXml);
XmlNode root = xmlDoc.GetElementsByTagName("jobs")[0];
XmlNode node = root.SelectSingleNode("Table");

Load metodu
Sınıfı dosya, textreader veya url gibi bir kaynaktan yükler. Aşağıdakine benzer bir kod kullanılabilir.
XmlDocument Doc = new XmlDocument();
 Doc .Load(@"D:\saraxml.txt");
//finding all nodes called "Name" 
XmlNodeList xmlnodelist = Doc.GetElementsByTagName("Name");
foreach (XmlNode c in xmlnodelist)
{
    string Name=c.InnerText;//xml tag'i içindeki metni al
}
LoadXML metodu
Sınıfı dosya yerine bir string'den yükler.
Örnek:
SelectSingleNode
Konuyu XPath başlıklı yazıya taşıdım.

SelectNodes
Konuyu XPath başlıklı yazıya taşıdım.

WriteTo
Bu metod XMLTestWriter ile beraber kullanılırsa, okuması daha kolay xml dosyaları oluşturulur. Örnek:

C++
Tiny XML
Aşağıdaki XML'i parse eden bir örnek

<Parent>
  <Children>
    <Child Name="A" Size="1"/>
    <Child Name="B" Size="2"/>
  </Children>
<Parent>

Tiny XML'de parent düğüme eriştikten sonra ismi bilinen tüm alt düğümleri dolaşmak için kurulan döngü şöyle
XMLElement parent = //..
XMLElement child = parent->FirstElement ("");
child = child->NextSiblingElement ("");

#include <tinyxml2.h>
using namespace tinyxml2;
XMLDocument doc;
doc.LoadFile ("path/to/xml");
XMLElement children = doc.FirstChildElement ("Parent")->FirstChildElement ("Children");
for (XMLElement child = children->FirstChildElement ("Child");
     child != NULL;
     child = child->NextSiblingElement ("Child") )
{
    cout << child->Attribute ("Name");
    cout << child->IntAttribute ("Size");
}
XML Namespace
Aynı XML Tag'inin accouting ve full isimli iki farklı namspace içinde kullanımı örneği.

<acct:customer xmlns:act="http://www.mycom.com">
</acct:customer>

<full:customer xmlns:act="http://www.yourcom.com">
</full:customer>


XSD Nedir?
Kısaca xml dosyasının yapısını tanımlar diyebiliriz. XSD dosyasında xs:complexType ile başlayan birden fazla  tanım olabilir. Örnek:



Hiç yorum yok:

Yorum Gönder