【问题标题】:How to sort two XML documents while merging them into one?如何在将两个 XML 文档合并为一个时对它们进行排序?
【发布时间】:2011-11-03 11:26:40
【问题描述】:

我必须使用 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. 合并两个文档,按发布日期排序

请帮忙。提前致谢。

【问题讨论】:

    标签: xml sorting merge xslt-2.0


    【解决方案1】:

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

    首先是对您正在导入的数据进行规范化,以便在您进行合并和排序时 您具有相似结构的元素。

    第二个是从那些规范化的文档中选择和排序。

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

    一旦你的数据充分标准化,排序就变成了 比较简单。

    问候

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

    【讨论】:

      猜你喜欢
      • 2022-10-04
      • 1970-01-01
      • 2023-03-12
      • 2023-03-18
      • 1970-01-01
      • 2012-05-11
      • 2016-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多