Как отсортировать два XML-документа при объединении их в один? - PullRequest
0 голосов
/ 03 ноября 2011

Я должен объединить два XML-документа, используя xslt 1.0. Каждый XML-документ содержит несколько статей с заголовком и датой публикации в одной. Условие состоит в том, что статьи в новом XML-документе должны быть отсортированы в порядке возрастания по дате. Ниже приведены образцы документов: doc1.xml Бревно движется 05-05 / 2002 Некоторый текст Антисемитизм в Европе 12-05 / 2002 еще немного текста

А документом doc2.xml является

<document>
  <article>
    <head>Launch Year A Success For Alliance</head>
    <text>
        <paragraph>para text</paragraph>
        <paragraph>para text</paragraph>
        <paragraph>para text</paragraph>
    </text>
    <date>
        <day>17</day>
        <month>05</month>
        <year>2002</year>
    </date>
    <source>Alliance</source>
    <portal>Finance</portal>
    <ID number="27"/>
  </article>
  <article>
    <head>ISA Savers Could Lose Tax Relief</head>
    <text>
        <paragraph>para text</paragraph>
        <paragraph>para text</paragraph>
        <paragraph>para text</paragraph>
        <paragraph>para text</paragraph>
    </text>
    <date>
        <day>10</day>
        <month>05</month>
        <year>2002</year>
    </date>
    <source>Money</source>
    <portal>Finance</portal>
    <ID number="26"/>
  </article>
</document>

и желаемый результат:

<document>
  <article>
<head>The logjam moves</head>
      <date>
    <day>05</day>
    <month>05</month>
    <year>2002</year>
</date>
    <text>Some text </text>
  </article>
  <article>
<head>ISA Savers Could Lose Tax Relief</head>
<text> para text  para text para text para text </text>
<date>
  <day>10</day>
  <month>05</month>
  <year>2002</year>
    </date>
  </article>
  <article>
<head>Anti-Semitism in Europe</head>
    <date>
  <day>12</day>
      <month>05</month>
      <year>2002</year>
    </date>
    <text>some more text</text>
  </article>
  <article>
    <head> Launch Year A Success For Alliance </head>
    <text> para text  para text para text para text     </text>
    <date>
      <day>17</day>
      <month>05</month>
      <year>2002</year>
    </date>
  </article>
</document>

И моя таблица стилей:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:param name="doc1File">doc1.xml</xsl:param>
  <xsl:variable name="doc1" select="document($doc1File)" as="document-node()"/>
  <xsl:param name="doc2File">doc2.xml</xsl:param>
  <xsl:variable name="doc2" select="document($doc2File)" as="document-node()"/>
  <xsl:template match="/">
    <xsl:for-each select ="$finance/document/article">
      <xsl:value-of select="head"/>
      <xsl:value-of select="text"/>
      <xsl:value-of select="date"/>
    </xsl:for-each>
    <xsl:for-each select ="$economist/document/ARTICLE">
      <xsl:value-of select="headline"/>
      <xsl:value-of select="text"/>
      <xsl:value-of select="date"/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Как видите, мне удалось распечатать только значения элементов. Я не могу понять, как

  1. Разобрать по-разному упомянутую дату в doc1.xml и
  2. Объединение двух документов, отсортированных по дате их публикации

Пожалуйста, помогите. заранее спасибо.

1 Ответ

0 голосов
/ 29 ноября 2011

У меня есть решение для вас. Вам нужно разбить проблему на несколько этапов.

Первый - нормализация импортируемых вами данных, чтобы при объединении и сортировке элементы у вас похожая структура.

Затем выбирается и сортируется эти нормализованные документы.

Для этого я использовал несколько режимов, чтобы выделить различные преобразования ( вам может быть проще убедиться, что ваши исходные документы имеют одинаковый формат начать). На этом этапе вы не хотите совпадать с "/" импортированные документы - в противном случае вы применяете совпадение '/', которое мы используем для слияния.

Как только ваши данные достаточно нормализованы, сортировка становится относительно просто.

Привет

    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:exsl="http://exslt.org/common"
                                    extension-element-prefixes="exsl">

        <xsl:param name="doc1File">./doc1.xml</xsl:param>
        <xsl:param name="doc2File">./doc2.xml</xsl:param>

        <xsl:variable name="doc1">
            <xsl:apply-templates select="document($doc1File)/*" mode="import1"/>
        </xsl:variable>
        <xsl:variable name="doc2">
            <xsl:apply-templates select="document($doc2File)/*" mode="import2"/>
        </xsl:variable>

        <!-- merging and sorting -->
        <xsl:template match="/">
            <document>
                <xsl:apply-templates select="
                    exsl:node-set($doc1)/document/article|
                    exsl:node-set($doc2)/document/article">
                    <xsl:sort select="date/year"/>
                    <xsl:sort select="date/month"/>
                    <xsl:sort select="date/day"/>
                </xsl:apply-templates>
            </document>
        </xsl:template>

        <xsl:template match="article">
            <xsl:copy>
                <xsl:apply-templates select="head|text|date"/>
            </xsl:copy>
        </xsl:template>

        <xsl:template match="*">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates/>
            </xsl:copy>
        </xsl:template>

        <!-- transforming document 1 -->
        <xsl:template match="ARTICLE" mode="import1">
            <article>
                <head><xsl:value-of select="headline"/></head>
                <date>
                    <day><xsl:value-of select="substring(date,1,2)"/></day>
                    <month><xsl:value-of select="substring(date,4,2)"/></month>
                    <year><xsl:value-of select="substring(date,7,4)"/></year>
                </date>
                <xsl:apply-templates select="text" mode="import1"/>
            </article>
        </xsl:template>

        <xsl:template match="*" mode="import1">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates mode="import1"/>
            </xsl:copy>
        </xsl:template>

    <!-- transforming document 2 -->

        <xsl:template match="text" mode="import2">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates select="paragraph" mode="import2"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="paragraph" mode="import2">
            <xsl:choose>
                <xsl:when test="position() != last()">
                    <xsl:value-of select="normalize-space(.)"/><xsl:text> </xsl:text>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="normalize-space(.)"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>

        <xsl:template match="*" mode="import2">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates mode="import2"/>
            </xsl:copy>
        </xsl:template>

    </xsl:stylesheet>

Мой результат

<?xml version="1.0"?>
<document>
  <article>
    <head>The logjam moves</head>
    <date>
      <day>05</day>
      <month>05</month>
      <year>2002</year>
    </date>
    <text>Some text </text>
  </article>
  <article>
    <head>ISA Savers Could Lose Tax Relief</head>
    <text>para text para text para text para text</text>
    <date>
      <day>10</day>
      <month>05</month>
      <year>2002</year>
    </date>
  </article>
  <article>
    <head>Anti-Semitism in Europe</head>
    <date>
      <day>12</day>
      <month>05</month>
      <year>2002</year>
    </date>
    <text>some more text</text>
  </article>
  <article>
    <head>Launch Year A Success For Alliance</head>
    <text>para text para text para text</text>
    <date>
      <day>17</day>
      <month>05</month>
      <year>2002</year>
    </date>
  </article>
</document>
...