基于节点值进行分组(如果仅存在使用XSLT 1.0

时间:2017-05-06 11:55:03

标签: xslt xslt-1.0 xslt-grouping

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

我有以下输入xml:

   <?xml version="1.0" encoding="UTF-8"?>
    <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>
       <row>
          <ISSUEID>I6</ISSUEID>
          <ISSUEBA>MEDICAID</ISSUEBA>
          <OBJECTID>10</OBJECTID>
          <OBJECTBA>MEDICAID</OBJECTBA>
       </row>
       <row>
          <CASEID>C11</CASEID>
          <CASEBA>MEDICAID</CASEBA>
          <OBJECTID>11</OBJECTID>
          <OBJECTBA>MEDICAID</OBJECTBA>
       </row>
    </results>

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

  

如果我有<CASEID>,则<CASE>标记应该在那里。如果我有   <ISSUEID>,然后<ISSUE>标记应该在那里。如果我有   <OBJECT>,然后<OBJECTID>标记应该在那里。背后的原因   这是一些行元素可能有<CASEID> <ISSUEID>   <OBJECTID>而有些则没有。如果没有<CASE><SOURCE>可以直接在其下<ISSUE>

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

例如:

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

2)列出所有<ISSUEID>&amp; <ISSUEBA> <CASEID>在不同的<row>中相等的所有<ISSUE>&amp; <CASE>最近创建的 <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>

例如:

<ISSUEID>

3)列出<row><SOURCE><ISSUE>&#39}中相同的所有<CASE>&#39},并将它们移到新的<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> <ISSUE> <ISSUEID>I6</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> <SOURCE> <OBJECTID>10</OBJECTID> <OBJECTBA>MEDICAID</OBJECTBA> </SOURCE> </ISSUE> <CASE> <CASEID>C11</CASEID> <CASEBA>MEDICAID</CASEBA> <SOURCE> <OBJECTID>11</OBJECTID> <OBJECTBA>MEDICAID</OBJECTBA> </SOURCE> </CASE> </results> 标记内的public double setPractical(double practical_mark){ //... return practical_mark;//return the result, and assign it to another varibale } 标记肯定属于double result = setPractical(practical_mark); 。 例如:

public double setPractical() {
//-------------------------^------no need to pass your variable here
    Scanner read = new Scanner(System.in);
    System.out.println("Enter the practical_mark");

    //just create it a initialize it in your method, like this
    double practical_mark = read.nextDouble();

    if (practical_mark > 10) {
        practical_mark = 0;
    }
    return practical_mark;
}

最终输出xml应如下所示:

na.omit("babies")

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

1 个答案:

答案 0 :(得分:2)

您仍然可以使用Muenchian Grouping解决此问题。如果您最初按CASEID进行分组,但CASEID可能不存在,则可以定义第一个键,如此

 <xsl:key name="case" match="row" use="string(CASEID)" />

因此,对于第一个键,没有row的{​​{1}}元素将与空字符串匹配并组合在一起。

要在CASEID内按INDEXID进行分组,您可以使用这样的密钥,因为这仍然可以不使用CASEID(因为CASEID返回一个字符串)< / p>

concat

要选择不同的<xsl:key name="issue" match="row" use="concat(CASEID, '|', ISSUEID)" /> 记录,您可以执行此操作:

CASEID

但是,在与此模式的<xsl:apply-templates select="row[generate-id() = generate-id(key('case', string(CASEID))[1])]" mode="case" /> 元素匹配的模板中,您需要row语句来检查xsl:choose是否存在。如果它们确实存在,您将创建CASEID元素。如果没有,您将应用下一个级别的密钥。

<CASE>

试试这个XSLT

    <xsl:choose>
        <xsl:when test="CASEID">
            <CASE>
                <!-- Apply next key -->
            </CASE>
        </xsl:when>
        <xsl:otherwise>
              <!-- Apply next key -->
        </xsl:otherwise>
    </xsl:choose>