XSL изменение исходного xml дерева, и дальнейшая обработка в шаблоне.

MagicGTS

Новичок
XSL изменение исходного xml дерева, и дальнейшая обработка в шаблоне.

Никак немогу найти, есть ли возможность изменить исходное дерево документа (добавить туда новые елементы и т.п.), а затем продолжить обработку.
Для примера
PHP:
<xml>
 <first_data>
  <item1>qwerty</item1>
  <item2>ytrewq</item2>
  <item5>dsjhsk</item5>
 </first_data>
 <second_data>
  <item1>sdgsg</item1>
  <item3>sgsed</item2>
  <item4>segds</item5>
 </second_data>
</xml>
Это примерный исходный документ, при обработке мне требуется сделать "пересечение" first_data и second_data с приоритетом first_data, и добавить результат в исходное дерево, чтобы получилось так:
PHP:
<xml>
 <first_data>
  <item1>qwerty</item1>
  <item2>ytrewq</item2>
  <item5>dsjhsk</item5>
 </first_data>
 <second_data>
  <item1>sdgsg</item1>
  <item3>sgsed</item3>
  <item4>segds</item4>
 </second_data>
 <result_data>
  <item1>qwerty</item1>
  <item2>ytrewq</item2>
  <item3>sgsed</item3>
  <item4>segds</item4>
  <item5>dsjhsk</item5>
 </result_data>
</xml>
И потом полученый результат продолжить обрабатывать. Счас получается некрасиво, сначало первый шаблон делает пересечение, а затем вызываю сного преобразование другим шаблоном. Видать совсем голова не варит... изменение вносимые с помощью <xsl:element> сразу попадают ещё и в выходной документ, а мне это ненужно (хотя элементы созданые таки образом я тоже могу после создания использовать как исходные) но то что они сразу врезаются в выходной документ мне ненужно...
 

Alexandre

PHPПенсионер
MagicGTS
dom функции (domxml в зависимости от версии пхп)

строишь два ассоциативных массива (для ферст и секонд дата) и ищешь их пересечение,
потом используя addChild добавляешь пересечение в узел result, который добавляешь в корень исходного дерева.

но я бы сделал XSLT преобразование, хотя дольше по времени, но решение красивее.
для определения перечечения использовалбы ключи <xsl:key ... />.
 

MagicGTS

Новичок
Я делаю в xsl, но видимо вы непоняли. Мне нужно средствами xsl изменить исходный xml документ (добавив новые элементы), но таким образом чтобы изменения непопали сразу в выходной поток! <xsl:element> ведь сразу в выходной поток пихает данные. А мне нужно создать "временные" узлы в документе, и затем их в шаблоне обработать. Это средство сделать более "красиво". Если мне из php менять документ, то это изменение логики построения выходных данных, а это мне не нужно. У меня прога генерит тот самый "примерный" документ, а дальше его брабатывает xsl процессор, который использует клиент. Во, написал много, и вроде раскрыл суть проблемы.
P.S. Все манипуляции с документом мне нужно выполнять средствами xsl, желательно за один вызов шаблона (всмысле xsl файла), типа сказал: вот xml, вот xsl. Сделай мне из него нечто.
 

[DAN]

Старожил PHPClub
А что мешает разбить трансформацию на два этапа?
На первом отрабатываем "препроцессорный" шаблон и получаем нужную структуру документа. Проще говоря, делаем враппер данных.
На втором генерим результирующий документ.
 

MagicGTS

Новичок
Это выглядет неочень красиво... Два раза вызывать xsl преобразования. Вот если можно как нибудь вызвать один шаблон типа call-template и затем ещё один, вот тогда ещё неплохо...
Тогда доп. вопросец. XPath выраженеце. Нужно выбрать из выше приведенного документа элемент first_data/item1 или second_data/item1 или ничего. Можно рисовать <xsl:choose><xsl:when> но это громоздко... былобы неплохо получить что-то типа
PHP:
 <xsl:choose>
                      <xsl:when test="/xml/[first bla bla second]_data/item1">
                          <xsl:value-of select="/xml/[first bla bla second]_data/item1" />
                      </xsl:when>
                      <xsl:otherwise>
                        Empty
                      </xsl:otherwise>
                    </xsl:choose>
А еще лучше вообще в одну строчку ;)
Пока не нашел решения, может кто найдет быстрей?
 

Alexandre

PHPПенсионер
Мне нужно средствами xsl изменить исходный xml д
так и надо было начинать.
Код:
<xml> 
 <first_data> 
  <item1>qwerty</item1> 
  <item2>ytrewq</item2> 
  <item5>dsjhsk</item5> 
 </first_data> 
 <second_data> 
  <item1>sdgsg</item1> 
  <item3>sgsed</item3> 
  <item4>segds</item4> 
 </second_data>
первые два тега first_data & second_data переносятся банальным <xsl:copy>
а result_data осуществляется путем использование <xsl:key> я уже писал об этом. Прием называется Группировка методом Мюнча (могу ошибиться в написании фамилии).

Могу посоветовать почитать книгу "Технология - XSLT" или поискать статью в интернете, как это делать.

Также могу посоветовать мою статью http://www.raleigh.ru/a/pub/2005/templates.html?page=1 где можешь найти много полезных приемов.
(продолжение (часть 2) по использованию <xsl:key> написано но пока не опубликованно),

-~{}~ 12.05.06 13:05:

А что мешает разбить трансформацию на два этапа?
в два этапа - это не выход, как-то кривовато и отражается на скорости.
хотя есть иногда такие случаи, когда в один этап ну ни как не выходит...
 

MagicGTS

Новичок
А можно такое выражение сбацать, чтобы оно проверяло есть ли узел first_data/item1, если есть то возвращало его, а если нет то проверяло second_data/item1 ну и с ним тоже самое, если ниодного узла несуществует то вернуть false? Есть же конструкции для атрибутов... Что-то в документации ничего понять немогу, очень мало примеров, либо совсем простенькие либо их совсем нет.
 
Сверху