Как я могу объединить дочерние узлы в двух или более файлах XML, используя XSL? - PullRequest
2 голосов
/ 25 августа 2011

Я пытаюсь объединить файлы XML, используя XSL. Я искал подсказки на stackoverflow, google и в других местах. Я нашел похожие вопросы или темы, но ничего, что точно соответствует тому, что я пытаюсь сделать.

Я пытался использовать то, что могу почерпнуть из этих источников, но, похоже, не могу получить желаемый результат. Так что ... S / O для быстрой консультации!

Вот мой текущий подход:

Входной файл1.xml

<?xml version="1.0" encoding="UTF-8"?>
<protocol>
  <message_exchanges>
    <message_exchange id="1"/>
    <message_exchange id="2"/>
  </message_exchanges>
  <message_types>
    <message_type id="1"/>
    <message_type id="2"/>
    <message_type id="3"/>
  </message_types>
</protocol>

Входной файл2.xml

<?xml version="1.0" encoding="UTF-8"?>
<protocol>
  <message_exchanges>
    <message_exchange id="3"/>
    <message_exchange id="4"/>
  </message_exchanges>
  <message_types>
    <message_type id="4"/>
    <message_type id="5"/>
    <message_type id="6"/>
  </message_types>
</protocol>

Ввод index.xml

<?xml version="1.0" encoding="UTF-8"?>
<index>
  <component>file1.xml</component>
  <component>file2.xml</component>
</index>

combine.xsl

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

<xsl:output method="xml" version="1.0" indent="yes"/>

<xsl:template match="index">
   <xsl:apply-templates/>
</xsl:template>

<xsl:template match="component">
  <xsl:apply-templates select="document(.)"/>
</xsl:template>

.....help me fix / finish this file

</xsl:stylesheet>

desired_result.xml

<?xml version="1.0" encoding="UTF-8"?>
<protocol>
  <message_exchanges>
    <message_exchange id="1"/>
    <message_exchange id="2"/>
    <message_exchange id="3"/>
    <message_exchange id="4"/>
  </message_exchanges>
  <message_types>
    <message_type id="1"/>
    <message_type id="2"/>
    <message_type id="3"/>
    <message_type id="4"/>
    <message_type id="5"/>
    <message_type id="6"/>
  </message_types>
</protocol>

1000 бонусных баллов, если вы можете помочь мне добавить атрибут на лету:

<message_type id="1" src="file1.xml"/>
<message_type id="4" src="file2.xml"/>

Я загружаю и применяю XSL-файл к индексному XML-файлу, используя PHP-XSLTProcessor, поэтому я могу загрузить имена исходных файлов в процессор в качестве параметра, если это будет полезно / проще сделать, добавив атрибут src.

Спасибо! Дайте мне знать, если я смогу что-то прояснить.

Самая полезная ссылка, которую я нашел, и основа моего нынешнего подхода

Ответы [ 2 ]

2 голосов
/ 25 августа 2011

Это тот случай, когда параметры шаблона становятся полезными. Это самое короткое и простое преобразование, которое я на самом деле могу произвести. Он обрабатывает два или более файлов.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>

    <xsl:template match="index">
        <protocol>
            <message_exchanges>
                <xsl:apply-templates select="component">
                    <xsl:with-param name="message" select="'message_exchanges'"/>
                </xsl:apply-templates>
            </message_exchanges>
            <message_types>
                <xsl:apply-templates select="component">
                    <xsl:with-param name="message" select="'message_types'"/>
                </xsl:apply-templates>
            </message_types>
        </protocol>
    </xsl:template>

    <xsl:template match="component">
        <xsl:param name="message"/>
        <xsl:apply-templates select="document(.)/*/*[name()=$message]/*">
            <xsl:with-param name="comp" select="."/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="message_type|message_exchange">
        <xsl:param name="comp" select="''"/>
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="src">
                <xsl:value-of select="$comp"/>
            </xsl:attribute>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

с выводом:

<protocol>
   <message_exchanges>
      <message_exchange id="1" src="file1.xml"/>
      <message_exchange id="2" src="file1.xml"/>
      <message_exchange id="3" src="file2.xml"/>
      <message_exchange id="4" src="file2.xml"/>
   </message_exchanges>
   <message_types>
      <message_type id="1" src="file1.xml"/>
      <message_type id="2" src="file1.xml"/>
      <message_type id="3" src="file1.xml"/>
      <message_type id="4" src="file2.xml"/>
      <message_type id="5" src="file2.xml"/>
      <message_type id="6" src="file2.xml"/>
   </message_types>
</protocol>
0 голосов
/ 25 августа 2011

Это преобразование :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vFilename1" select="/*/component[1]"/>
 <xsl:variable name="vFilename2" select="/*/component[2]"/>

 <xsl:template match="index">
  <protocol>
    <xsl:apply-templates select="document($vFilename1)"/>
  </protocol>
 </xsl:template>

 <xsl:template match="message_exchanges|message_types">
  <xsl:copy>
   <xsl:apply-templates/>

   <xsl:apply-templates select=
       "document($vFilename2)/*/*[name()=name(current())]/*">
     <xsl:with-param name="pFilename" select="$vFilename2"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="message_exchanges/* | message_types/*">
  <xsl:param name="pFilename" select="$vFilename1"/>

  <xsl:copy>
   <xsl:copy-of select="@*"/>
   <xsl:attribute name="src">
    <xsl:value-of select="$pFilename"/>
   </xsl:attribute>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<index>
  <component>file1.xml</component>
  <component>file2.xml</component>
</index>

создает искомое, правильный результат :

<protocol>
   <message_exchanges>
      <message_exchange id="1" src="file1.xml"/>
      <message_exchange id="2" src="file1.xml"/>
      <message_exchange id="3" src="file2.xml"/>
      <message_exchange id="4" src="file2.xml"/>
   </message_exchanges>
   <message_types>
      <message_type id="1" src="file1.xml"/>
      <message_type id="2" src="file1.xml"/>
      <message_type id="3" src="file1.xml"/>
      <message_type id="4" src="file2.xml"/>
      <message_type id="5" src="file2.xml"/>
      <message_type id="6" src="file2.xml"/>
   </message_types>
</protocol>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...