使用XSLT 1.0

时间:2017-05-06 09:49:40

标签: xslt xslt-1.0 xslt-grouping

我的要求稍微复杂一点。我只能使用XSLT 1.0。我能够使用XSLT 2.0获得解决方案,但我需要使用1.0的解决方案。

我有以下输入xml:

<results>
       <row>
          <CASEID>C1</CASEID>
          <CASEBA>MEDICAID</CASEBA>
          <ISSUEID>I1</ISSUEID>
          <ISSUEBA>MEDICAID</ISSUEBA>
          <OBJECTID>1</OBJECTID>
          <OBJECTBA>MEDICAID</OBJECTBA>
       </row>
       <row>
          <CASEID>C1</CASEID>
          <CASEBA>MEDICAID</CASEBA>
          <ISSUEID>I2</ISSUEID>
          <ISSUEBA>MEDICAID</ISSUEBA>
          <OBJECTID>2</OBJECTID>
          <OBJECTBA>MEDICAID</OBJECTBA>
       </row>
       <row>
          <CASEID>C1</CASEID>
          <CASEBA>MEDICAID</CASEBA>
          <ISSUEID>I1</ISSUEID>
          <ISSUEBA>MEDICAID</ISSUEBA>
          <OBJECTID>extra</OBJECTID>
          <OBJECTBA>MEDICAID</OBJECTBA>
       </row>
       <row>
          <CASEID>C2</CASEID>
          <CASEBA>MEDICAID</CASEBA>
          <ISSUEID>I3</ISSUEID>
          <ISSUEBA>MEDICAID</ISSUEBA>
          <OBJECTID>3</OBJECTID>
          <OBJECTBA>MEDICAID</OBJECTBA>
       </row>
    </results>

我必须按照以下条件使用XSLT将上述xml转换为更简单的xml:

1)第一个目标是将新<CASEID>标记下的值相同的所有<CASE><CASEBA>节点一起移动。

例如:

<CASE>
   <CASEID>C1</CASEID>
   <CASEBA>MEDICAID</CASEBA>
</CASE>

2)列出<ISSUEID><ISSUEBA> <CASEID>在不同<row>中相等的所有<ISSUE>&amp; <CASE>并将其移至新标记{{1}下在最近创建的 <CASE> <CASEID>C1</CASEID> <CASEBA>MEDICAID</CASEBA> <ISSUE> <ISSUEID>I1</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> </ISSUE> <ISSUE> <ISSUEID>I2</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> </ISSUE> </CASE> 代码中。

例如:

<OBJECTID>

3)列出<ISSUEID>在不同<row>中相等的所有<SOURCE>,并将其移至<ISSUE>内的新<CASE>标记内1}}标签肯定会在<CASE> <CASEID>C1</CASEID> <CASEBA>MEDICAID</CASEBA> <ISSUE> <ISSUEID>I1</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> <SOURCE> <OBJECTID>1</OBJECTID> <OBJECTBA>MEDICAID</OBJECTBA> </SOURCE> <SOURCE> <OBJECTID>extra</OBJECTID> <OBJECTBA>MEDICAID</OBJECTBA> </SOURCE> </ISSUE> <ISSUE> <ISSUEID>I2</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> <SOURCE> <OBJECTID>2</OBJECTID> <OBJECTBA>MEDICAID</OBJECTBA> </SOURCE> </ISSUE> </CASE> 之下。 例如:

<?xml version="1.0" encoding="UTF-8"?>

  <results>
   <CASE>
      <CASEID>C1</CASEID>
      <CASEBA>MEDICAID</CASEBA>
      <ISSUE>
         <ISSUEID>I1</ISSUEID>
         <ISSUEBA>MEDICAID</ISSUEBA>
         <SOURCE>
            <OBJECTID>1</OBJECTID>
            <OBJECTBA>MEDICAID</OBJECTBA>
         </SOURCE>
         <SOURCE>
            <OBJECTID>extra</OBJECTID>
            <OBJECTBA>MEDICAID</OBJECTBA>
         </SOURCE>
      </ISSUE>
      <ISSUE>
         <ISSUEID>I2</ISSUEID>
         <ISSUEBA>MEDICAID</ISSUEBA>
         <SOURCE>
            <OBJECTID>2</OBJECTID>
            <OBJECTBA>MEDICAID</OBJECTBA>
         </SOURCE>
      </ISSUE>
   </CASE>
   <CASE>
      <CASEID>C2</CASEID>
      <CASEBA>MEDICAID</CASEBA>
      <ISSUE>
         <ISSUEID>I3</ISSUEID>
         <ISSUEBA>MEDICAID</ISSUEBA>
         <SOURCE>
            <OBJECTID>3</OBJECTID>
            <OBJECTBA>MEDICAID</OBJECTBA>
         </SOURCE>
      </ISSUE>
   </CASE>
</results>

最终输出xml应如下所示:

$('.left:not(#target)').click(function() {
console.log("clicked");
});

如果我没有正确解释我的要求,请原谅我。如果您需要任何其他信息,请询问我。如果有人帮助我,真的很棒。

1 个答案:

答案 0 :(得分:3)

在上一个问题(Transforming xml based on node values)中,答案提到了在XSLT 1.0中使用名为Muenchian Grouping的技术。在您的情况下,您有嵌套分组。您首先按CASEID进行分组,然后按CASEIDISSUEID分组,最后按CASEIDISSUEIDOBJECTID分组

这意味着定义三个键

<xsl:key name="case" match="row" use="CASEID" />
<xsl:key name="issue" match="row" use="concat(CASEID, '|', ISSUEID)" />
<xsl:key name="object" match="row" use="concat(CASEID, '|', ISSUEID, '|', OBJECTID)" />

要按CASEID进行分组,您可以选择每个组的第一个元素,如此

<xsl:apply-templates select="row[generate-id() = generate-id(key('case', CASEID)[1])]" mode="case" />

(我在这里使用mode,因为最终的XSLT将有多个匹配row的模板,所以你需要区分它们。)

在匹配模板中,然后在不同的ISSUEID值中按CASEID进行分组,您可以执行此操作。

<xsl:apply-templates select="key('case', CASEID)[generate-id() = generate-id(key('issue', concat(CASEID, '|', ISSUEID))[1])]" mode="issue" />

然后,您将在另一个模板中按OBJECTID执行类似的操作。

试试这个XSLT

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

    <xsl:key name="case" match="row" use="CASEID" />
    <xsl:key name="issue" match="row" use="concat(CASEID, '|', ISSUEID)" />
    <xsl:key name="object" match="row" use="concat(CASEID, '|', ISSUEID, '|', OBJECTID)" />

    <xsl:template match="results">
        <xsl:copy>
            <xsl:apply-templates select="row[generate-id() = generate-id(key('case', CASEID)[1])]" mode="case" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="row" mode="case">
        <CASE>
            <xsl:apply-templates select="CASEID|CASEBA" />
            <xsl:apply-templates select="key('case', CASEID)[generate-id() = generate-id(key('issue', concat(CASEID, '|', ISSUEID))[1])]" mode="issue" />
        </CASE>
    </xsl:template>

    <xsl:template match="row" mode="issue">
        <ISSUE>
            <xsl:apply-templates select="ISSUEID|ISSUEBA" />
            <xsl:apply-templates select="key('issue', concat(CASEID, '|', ISSUEID))[generate-id() = generate-id(key('object', concat(CASEID, '|', ISSUEID, '|', OBJECTID))[1])]" mode="object" />
        </ISSUE>
    </xsl:template>

    <xsl:template match="row" mode="object">
        <OBJECT>
            <xsl:apply-templates select="OBJECTID|OBJECTBA" />
        </OBJECT>
    </xsl:template>

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