Archive for the ‘DomDocument’ Category

Получение пути через DOMXPath

Wednesday, December 10th, 2008
$a = "<body><head><title>Page Title</title></head></body>";
$dom = new DOMDocument('1.0', 'utf-8');
$dom->preserveWhiteSpace = false;
$dom->loadXML($a);
$xpath = new DOMXPath($dom);
$arts = $xpath->query("/body/head/title");

foreach($arts as $art) {
    echo $art->nodeName . " - " . $art->nodeValue . "<br />";
}

Трансформация: php переменные в xslt

Thursday, February 21st, 2008

Начнем с того что создадим переменную в шаблоне и ее вывод

<xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="error_msg" select="0" />
<html>
<head>
        <title>Books
</head>
<body>
<h1>Books</h1>
<xsl:value-of select="$error_msg" />
...

Внимание! У вас может появится желание убрать нолик из select="0", не делайте этого, удалите select=”0″ целиком.

<xsl:param name="error_msg" />

Теперь присвоем значение переменной в момент трансформации на стороне php

$proc = new XSLTProcessor();
$doc = new DOMDocument();
$xsl = new XSLTProcessor();

$doc->load('test4.xsl');
$xsl->importStyleSheet($doc);

$doc->load('test.xml');
$xsl->setParameter(NULL, 'error_msg', 'search item not found');
echo $xsl->transformToXML($doc);

Трансформация через PHP

Wednesday, February 20th, 2008

Выглядит все довольно просто

$doc = new DOMDocument();
$xsl = new XSLTProcessor();

$doc->load('test4.xsl');
$xsl->importStyleSheet($doc);

$doc->load('test.xml');

// получить xml
echo $xsl->transformToXML($doc);

// получить DomDocument
$tdoc = $xsl->transformToDoc($doc)

// сохранить в файл
$xsl->transformToURI($doc, 'out.html');

XPath

Friday, January 25th, 2008

XPath (XML Path Language) является языком для обращения к частям XML-документа.

Вместе с DOMDocument, XPath, позволяет очень быстро извлекать данные из XML документа. Для примера берем документ XML.html. Теперь посчитаем сколько книг у каждого автора, они конечно написали намного больше, пусть это будет список книг этих авторов изданых неким издательством.
Можно конечно используя только DOMDocument, выполнить эту задачу. Но у нас есть XPath, так пусть поработает.

// загружаем документ
$dom = new DOMDocument;
$dom->load('books.xml');

// объявляем DOMXPath
$xpath = new DOMXPath($dom);

// получает масив авторов
$autors = $dom->getElementsByTagName('autor');

// создаем DOMXPath запрос подсчитать теги book
$query = 'count(book)';

// пропускаем через рекрусию
foreach($autors as $autor){
	$books = $xpath->evaluate($query, $autor);
	echo $autor->getAttribute('name') . " - " . $books ;
}

И вот результат

Robert Sheckley - 2
Isaac Asimov - 2
Ray Bradbury - 2
Frank Patrick Herbert - 1

Простую справку в контекстную

Thursday, January 17th, 2008

В больших проектах всегда создается подробный справочный раздел, пошаговые инструкции и общая информация. Над таким разделом работает редактор. Но вот когда дело доходит до контекстной справки то здесь возникает проблема. вроде как бы справочный раздел уже есть и формировать еще один но порезанный на кусочки дело муторное, к тому же надо постоянно следить за изменениями. Вот небольшое решение для создания простой контекстной справки. Во-первых нам нужен сам html файл со справкой
help.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
 <meta http-equiv="Content-Type"
   content="text/html; charset=utf-8" />
 <title>Untitled Document
</head>
<body>
 <div id="user_sessings">
  <h2>User settings

   in this section....
 </div>
 <div id="time_sessings">
  <h2>Time settings

  Time is most inportant for your ....
 </div>
</body>
</html>

Теперь создаем php файл, но перед этим мы вспомним что у DOMDocument проблемы с функцией getElementById поэтому берем надстройку над DOMDocument исправляет неправильный id на xml:id
get_help.php

include "DomDoc.php";

$dom = new DomDoc();
$dom->loadHTMLFile("help.html");
$part = $dom->getElementById($_GET[part]);
header ('Content-type: text/xml');
echo $dom->saveXML($part);

Вот и все теперь ставите на странице в нужном вам месте значок справки, вешаете на него JavaScript с Ajax который отправляет запрос на get_help.php?part=time_sessings и получаете возвратом кусок нужной вам справки, в нашем случае

<div id="time_sessings">
 <h2>Time settings

 Time is most inportant for your ....
</div>

и вставляете его в окно контекстной справки.

Работа с текстом в DomDocument

Monday, January 7th, 2008

В DomDocument встроено несколько удобных функций для работы с текстом. Возьмем для примера некий текстовый элемент.

<p>Hello world</p>

Получив его начнем его мучить, но в начале проверим, текстовый ли это элемент а не пустой узел, используя метод isElementContentWhitespace.

if ($textnode->nodeType == XML_TEXT_NODE &&
   ! $textnode->isElementContentWhitespace()) {
  echo "text element";
}

Теперь, из него можно извлечь часть отрывок

print $textnode->substringData(1,2);
//el

Присоединить

$textnode->appendData(", hi!");
//Hello world, hi!

Удалить

$textnode->deleteData(5,5);
//Hello

Заменить

$textnode->replaceData(0, 4, "Hi");
//Hi world

Вставить

$textnode->replaceData(5, "my ");
//Hello my world

Попробуй и поймай

Monday, January 7th, 2008

Try/catch одна из таких штук к которой отношение примерно как и ко всей технологии xml, штука хорошая, только куда вставить не поймешь. Вот пример использования. Тег не может носить цифровое имя, но если вдруг, то ошибки можно избежать с помощью Try/catch.

try {
	$test = new DOMElement("111");
} catch (DOMException $e) {
	var_dump($e);
}

Избавляемся от пробелов при загрузке

Saturday, January 5th, 2008

Загружая xml файл загружаются все включая форматирование, пробулы и отступы между узлами.

$xmldata = '<?xml version="1.0"?>
<root>
   <child>contents</child>
</root>'; 

$dom = new DOMDocument();
$dom->loadXML($xmldata);
echo $dom->saveXML();

на выходе получим тоже что и на входе

<?xml version="1.0"?>
<root>
   <child>contents</child>
</root>

Но если воспользоваться дополнительным параметром LIBXML_NOBLANKS, то можно убрать ненужное

$dom->loadXML($xmldata, LIBXML_NOBLANKS);

и вывод начинает выглядеть так

<root><child>contents</child></root>

Определение типа узла

Saturday, January 5th, 2008

В php есть 2 способа выяснить что за узел перед тобой, текст, тег, комментарий и т.д. Первый знаком с помощью числа; тег - 1, комментарий - 8.

if($child->nodeType==8){
   echo "коментарий - ".$child->nodeValue;
}

Второй, используя константы

if($child->nodeType==XML_COMMENT_NODE){
  echo "коментарий - ".$child->nodeValue;
}

Пусть буквы длиннее чем цифра, зато код понятнее. А вот и список констант:

1 - XML_ELEMENT_NODE
2 - XML_ATTRIBUTE_NODE
3 - XML_TEXT_NODE
4 - XML_CDATA_SECTION_NODE
5 - XML_ENTITY_REF_NODE
6 - XML_ENTITY_NODE
7 - XML_PI_NODE
8 - XML_COMMENT_NODE
9 - XML_DOCUMENT_NODE
10 - XML_DOCUMENT_TYPE_NODE
11 - XML_DOCUMENT_FRAG_NODE
12 - XML_NOTATION_NODE
13 - XML_HTML_DOCUMENT_NODE
14 - XML_DTD_NODЕ
15 - XML_ELEMENT_DECL_NODE
16 - XML_ATTRIBUTE_DECL_NODE
17 - XML_ENTITY_DECL_NODE
18 - XML_NAMESPACE_DECL_NODE

Удаляем пустые Xml узлы

Friday, December 21st, 2007

Попробуем осуществить это.

$dom  = new DOMDocument();
$root = $dom->createElement('html');
$firstFragment = $dom->createDocumentFragment();
$firstFragment->appendXML('<p>44</p><p/><p>55</p>');
$root->appendChild($firstFragment);
$dom->appendChild($root);
echo $dom->saveHTML();

Как результат получаем код.

<html>
<p>44</p>
<p></p>
<p>55</p>
</html>

Теперь вставим еще кусок кода.

foreach($root->childNodes as $chN){
    if(!$chN->hasAttributes() && !$chN->hasChildNodes()){
	$chN->parentNode->removeChild($chN);
    }
}
$dom->appendChild($root);

И получим вывод.

<html>
<p>44</p>
<p>55</p>
</html>