Объединение двух XML-файлов на основе уникальных узлов с использованием XSL - PullRequest
1 голос
/ 31 августа 2011

У меня есть два файла. Данные частично совпадают, но я хочу извлечь конкретную информацию из файла file2 и добавить в файл file1.

File1.xml выглядит так:

<content>
  <book>
    <id>111aaa</id>
    <author>John Doe</author>
    <title>This is a book</title>
    <price>$10.00</price>
  </book>
  <book>
    <id>111bbb</id>
    <author>Jane Doe</author>
    <title>This is another book</title>
    <price>$20.00</price>
  </book>
</content>

File2.xml выглядит так:

<content>
  <book>
    <id>111aaa</id>
    <author>John Doe</author>
    <year>2011</year>
    <pages>100</pages>
  </book>
  <book>
    <id>111bbb</id>
    <author>Jane Doe</author>
    <year>2010</year>
    <pages>200</pages>
  </book>
</content>

Я хочу извлечь теги года и страниц из файла file2, добавить его в файл file1 и получить файл file3.xml, который выглядит так:

<content>
  <book>
    <id>111aaa</id>
    <author>John Doe</author>
    <title>This is a book</title>
    <year>2011</year>
    <pages>100</pages>
    <price>$10.00</price>
  </book>
  <book>
    <id>111bbb</id>
    <author>Jane Doe</author>
    <title>This is a another book</title>
    <year>2010</year>
    <pages>200</pages>
    <price>$20.00</price>
  </book>
</content>

Я использую командную строку для запуска xsltproc:

xsltproc transform.xsl file1.xml> file3.xml

У меня есть следующий кусок в моем xsl, но он только объединяет данные первой книги. Вы знаете, как написать xsl для каждой книги?

<xsl:choose>
                           <xsl:when test="document('file2.xml')/content/book/id = id">
                               <xsl:for-each select="document('file2.xml')/content/book">
                               <xsl:element name="pages">
                               <xsl:value-of select="document('file2.xml')/content/book/pages"/>
                               </xsl:element>
                               <xsl:element name="year">
                                  <xsl:value-of select="document('file2.xml')/content/book/year"/> 
                               </xsl:element>
                                   </xsl:for-each>
                           </xsl:when>
                           <xsl:otherwise></xsl:otherwise>
                       </xsl:choose>

Ответы [ 2 ]

1 голос
/ 31 августа 2011

Перекрестные ссылки запрашивают использование ключа:

<xsl:key name="k1" match="book" use="id"/>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="book">
  <xsl:variable name="id" select="id"/>
  <xsl:apply-templates select="@* | id | author"/>
  <xsl:for-each select="document('file2.xml')">
    <xsl:apply-templates select="key('k1', $id)/year | key('k1', $id)/pages"/>
  </xsl:for-each>
  <xsl:apply-templates select="price"/>
</xsl:template>
1 голос
/ 31 августа 2011

Думаю, вы ищете что-то подобное. Исправление синтаксиса оставлено на ваше усмотрение.

<xsl:for-each select="book">
  <xsl:copy>
    <xsl:apply-templates/>
    <xsl:variable name="id" select="string(id)"/>
    <xsl:for-each select="document('file2.xml')/content/book[string(id)=$id]/*">
      <xsl:apply-templates/><!-- Add in a choose here if you just want to pick out certain fields, or in the for-each above -->
    </xsl:for-each>
  </xsl:copy>
</xsl:for-each>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...