如何在将两个XML文档合并为一个文档时对它们进行排序?

时间:2011-11-03 11:26:41

标签: xml sorting merge xslt-2.0

我必须使用xslt 1.0合并两个xml文档。每个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. 中提到的不同日期
  3. 合并两份文件,按其出版日期排序
  4. 请帮忙。提前谢谢。

1 个答案:

答案 0 :(得分:0)

我有一个解决方案给你。您需要将问题分解为几个步骤。

第一个是规范化您导入的数据,以便在进行合并和排序时 你有相似结构的元素。

然后选择第二个并从那些标准化文档中排序。

要做到这一点,我已经使用了许多模式来分离出各种变换( 您可能会发现更容易确保源文档的格式相同 开始)。此时的问题是你不想匹配的“/” 导入的文档 - 否则你最终会应用我们用来进行合并的'/'匹配。

一旦您的数据足够标准化,排序就会变成 相对简单。

此致

    <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>