Как вытащить Namespaces из XML?

Archangel

Новичок
Как вытащить Namespaces из XML?

Перечитал все мануалы и стандарты, но так и не смог найти...

Есть XML файл в котором объявлены namespaces, которые в самом документе не используются, но обязательно должны сущестовать. Необходимо получить uri этих пространств имен и их перфиксы.

К примеру:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:something="http://something.ru">
<xsl:template match="/">
<xsl:value-of select="@something:attribute" />
</xsl:template>
</xsl:stylesheet>

Из этого документа "вытаскиваются" следующий пространства имен:
1. xsl http://www.w3.org/1999/XSL/Transform
2. something http://something.ru

Есть ощущение, что как-то возможно вытащить с помощью DOM, напрямую (ни в стандарте, ни в документации к php не описано) не удалось найти. Есть идеи?
 

cDLEON

Онанист РНРСlub
[m]xml_parser_create_ns[/m]
Правда сам не использывал.

-~{}~ 29.11.07 17:28:

ЗЫ. А зачем писать собственный обработчик xsl ?
 

Archangel

Новичок
Автор оригинала: cDLEON
[m]xml_parser_create_ns[/m]
Правда сам не использывал.

-~{}~ 29.11.07 17:28:

ЗЫ. А зачем писать собственный обработчик xsl ?
Сколько не перечитывал, не смог найти строки где бы я сказал, что собираюсь писать собственный xsl процессор, не нашел.

XSLT был приведен как пример, так как это самый характерный случай где пространство имен должно быть объявлено, но может нигде (с точки зрения xml парсера) не встречаться в самом документе.

Что касается xml_parser_create_ns, привидите php-код который бы с его помощью вытаскивал все пространства имен из документа, у меня никаких идей на этот счет. :(

-~{}~ 30.11.07 09:38:

Сегодня под утро рещил эту задачу.

Откровенно говоря, решение было найдено еще вчера, но оно было не "красивым". Состояло оно в том, чтобы xml-элементы уже сформированной DOM-модели преводить обратно в текст:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:something="http://something.ru">

и вытаскивать с помощью PCRE пространства имен. Сохранять же их в DOM можно с помощью обыкновенного добавления атрибута в элемент:

// $element - DOMElement
$element->setAttribute('xmlns:something', 'http://something.ru');

Минус такого подхода в том что сама DOM модель не будет воспринимать добавленный атрибут как пространство имен, а при сохранении и повторном парсинге атрибут исчезнет вовсе (будет считан как простарнство имен).

Второе, более "красивое" решение нашел сегодня перебирая на досуге планы перехода на PHP 6.0, там поддержка таких средств как XMLReader и XMLWriter будет добавлена на уровне ядра, впрочем с версии 5.1 она уже build-in.

При чтении XMLReader'ом все пространства имен так же дублируются как атрибуты!

Иначе говоря, "читая":

<?xml version="1.0" ?>
<something:document something:attribute="value" xmlns:something="http://something.ru/something/" xmlns:somethingelse="http://something.ru/somethingelse/">
<something:node something:attribute="something" />
</something:document>

с помощью

// $parser - XMLReader, в которого загружен приведенный выше XML
$parser->read();
$count = $parser->attributeCount;
for ($i = 0; $i < $count; $i++)
{
$parser->moveToAttributeNo($i);
printf("%s = \"%s\" (%s, %s)\n", $parser->name, $parser->value, $parser->prefix, $parser->localName);
}

мы получим

xmlns:something = "http://something.ru/something/" (xmlns, something)
xmlns:somethingelse = "http://something.ru/somethingelse/" (xmlns, somethingelse)
something:attribute = "value" (something, attribute)

:)
 

alekciy

Новичок
Re: Как вытащить Namespaces из XML?

Автор оригинала: Archangel
Из этого документа "вытаскиваются" следующий пространства имен:
1. xsl http://www.w3.org/1999/XSL/Transform
Ну вполне нормальмально можно вытащить так:
PHP:
<?php
$xml = <<<TEXT
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:something="http://something.ru">
    <xsl:template match="/">
        <xsl:value-of select="@something:attribute" />
    </xsl:template>
</xsl:stylesheet>
TEXT;

$doc = new DOMDocument();
$doc->loadXML($xml);
echo $doc->documentElement->namespaceURI;

?>
А вытаскивать NS для something префикса смысла не вижу, если это не используется. Конечно можно придумать любую теоретическую задачу с целью её решения, но... разминка для ума?
 

Archangel

Новичок
alekciy
этот способ очевиден и упомняать собственно не стоит в силу того что поставленной задачи он не решает.

А на счет разминки для ума, я думаю что вы понимаете, что задача не пришла во сне, а реально встала такая необходимость. Собственно она уже полностью решена с помощью XMLReader/DOM.
 

alekciy

Новичок
Archangel
Ну п.1 то он как раз и решает. А то, что я привел это и есть DOM.
 
Сверху