2

我正在使用一些困难的标记,其中没有规范化的 ID。让我通过示例展示所说的标记可能是什么样的:

<listing>
    <foo fooid="81">Foo</foo>
    <bar barid="88">Bar</bar>
</listing>
<listing>
    <foo fooid="82">Foo</foo>
    <bar barid="81">Bar</bar>
</listing>
<listing>
    <foo fooid="83">Foo</foo>
    <bar barid="81">Bar</bar>
</listing>

在这种情况下,我需要能够填充到的<xsl:variable />ID 是 81,因为无论其标签如何,该 id 的表示次数最多。有没有一种简单的方法可以用 XSLT 做到这一点?理想情况下,当它说完后,我会有类似的东西:

<xsl:variable name="an_id">其中an_id等于81

已知点如下:

  • 标签总是被称为 foo 或 bar。
  • 属性总是被称为 fooid 或 barid
  • 我希望在变量中捕获的数字将在两个标签中的任何一个中至少列出一次
  • 我要捕获的数字肯定会在每个列表中至少出现一次。
  • 不相关的数字可能会或可能不会出现不止一次。

我正在使用 XSLT 1.0。变量名不是动态的。whatever它是静态的,只要它导出的值是上面的81就可以调用。

** 更新 **

我在上面粘贴的 XML 是示例,虽然我认为 Mads 的答案是正确的,但它不会解析,所以我正在使用我正在处理的真实 XML 进行更新。您可以在我的人为示例中看到等效项,<foo>并且<bar>正在尝试处理<hometeam>and<awayteam>标签,这些是要关注的关键。

<?xml version="1.0" standalone="no"?>
<message>
  <XML_File_ID>18996672</XML_File_ID>
  <heading>ABX%PHI-SKED</heading>
  <category>Statistics</category>
  <sport>NFL</sport>
  <title>2013 Philadelphia Eagles Schedule/Results</title>
  <season>2013</season>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4189</schedule_id>
    <Game_Date>09/09/2013</Game_Date>
    <Game_Time>06:55 PM</Game_Time>
    <week>1</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="081">Philadelphia</awayteam>
    <hometeam hometeamid="088">Washington</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>FedEx Field</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>ESPN</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4206</schedule_id>
    <Game_Date>09/15/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>2</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="083">San Diego</awayteam>
    <hometeam hometeamid="081">Philadelphia</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Lincoln Financial Field</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>CBS</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4253</schedule_id>
    <Game_Date>09/19/2013</Game_Date>
    <Game_Time>08:25 PM</Game_Time>
    <week>3</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="072">Kansas City</awayteam>
    <hometeam hometeamid="081">Philadelphia</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Lincoln Financial Field</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>NFL Network</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4331</schedule_id>
    <Game_Date>09/29/2013</Game_Date>
    <Game_Time>04:25 PM</Game_Time>
    <week>4</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="081">Philadelphia</awayteam>
    <hometeam hometeamid="067">Denver</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Sports Authority Field at Mile High Stadium</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4366</schedule_id>
    <Game_Date>10/06/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>5</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="081">Philadelphia</awayteam>
    <hometeam hometeamid="079">NY Giants</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>MetLife Stadium</Location>
    <Indoor>False</Indoor>
    <Turf>True</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4403</schedule_id>
    <Game_Date>10/13/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>6</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="081">Philadelphia</awayteam>
    <hometeam hometeamid="087">Tampa Bay</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Raymond James Stadium</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4419</schedule_id>
    <Game_Date>10/20/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>7</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="066">Dallas</awayteam>
    <hometeam hometeamid="081">Philadelphia</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Lincoln Financial Field</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4197</schedule_id>
    <Game_Date>10/27/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>8</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="079">NY Giants</awayteam>
    <hometeam hometeamid="081">Philadelphia</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Lincoln Financial Field</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4216</schedule_id>
    <Game_Date>11/03/2013</Game_Date>
    <Game_Time>04:05 PM</Game_Time>
    <week>9</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="081">Philadelphia</awayteam>
    <hometeam hometeamid="073">Oakland</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Oakland-Alameda County Coliseum</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4230</schedule_id>
    <Game_Date>11/10/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>10</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="081">Philadelphia</awayteam>
    <hometeam hometeamid="069">Green Bay</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Lambeau Field</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4251</schedule_id>
    <Game_Date>11/17/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>11</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="088">Washington</awayteam>
    <hometeam hometeamid="081">Philadelphia</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Lincoln Financial Field</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4302</schedule_id>
    <Game_Date>12/01/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>13</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="086">Arizona</awayteam>
    <hometeam hometeamid="081">Philadelphia</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Lincoln Financial Field</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4322</schedule_id>
    <Game_Date>12/08/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>14</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="068">Detroit</awayteam>
    <hometeam hometeamid="081">Philadelphia</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Lincoln Financial Field</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4350</schedule_id>
    <Game_Date>12/15/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>15</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="081">Philadelphia</awayteam>
    <hometeam hometeamid="076">Minnesota</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Mall of America Field at HHH Metrodome</Location>
    <Indoor>True</Indoor>
    <Turf>True</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4365</schedule_id>
    <Game_Date>12/22/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>16</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="063">Chicago</awayteam>
    <hometeam hometeamid="081">Philadelphia</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>Lincoln Financial Field</Location>
    <Indoor>False</Indoor>
    <Turf>False</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <listing>
    <season_type>Regular</season_type>
    <schedule_id>4391</schedule_id>
    <Game_Date>12/29/2013</Game_Date>
    <Game_Time>01:00 PM</Game_Time>
    <week>17</week>
    <ascore>0</ascore>
    <hscore>0</hscore>
    <awayteam awayteamid="081">Philadelphia</awayteam>
    <hometeam hometeamid="066">Dallas</hometeam>
    <TypeUpdate>P</TypeUpdate>
    <Status>
    </Status>
    <Location>AT&amp;T Stadium</Location>
    <Indoor>False</Indoor>
    <Turf>True</Turf>
    <TV_Listing>FOX</TV_Listing>
  </listing>
  <time_stamp> September 3, 2013, at 05:17 PM ET </time_stamp>
</message>

基本上我正在尝试获取主队的 ID。由于在列表之前它没有在上面标准化,我必须选择在每个列表中列出的团队(因此出现最多)。在本例中,Philadelphia 的 ID 为“081”,但是一旦您number()在 XSLT 处理器中运行它,它应该只是81.

这是我迄今为止根据 Mads 回答的样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" omit-xml-declaration="yes" />
  <xsl:strip-space elements="*" />

  <xsl:key name="id" match="@awayteamid | @hometeamid" use="."/>

  <xsl:template match="/message">
    <xsl:variable name="heading"><xsl:value-of select="heading"/></xsl:variable>
    <xsl:variable name="title"><xsl:value-of select="title"/></xsl:variable>
    <xsl:variable name="team_id">
      <xsl:for-each select="*/listing/*/@*">
         <xsl:sort select="count(key('id', .))" order="descending" data-type="number" />
         <xsl:if test="position()=1">
             <xsl:value-of select="."/>
         </xsl:if>
     </xsl:for-each>
   </xsl:variable>

    {
     "team_id": <xsl:value-of select="number($team_id)" /> 
    }
  </xsl:template>
</xsl:stylesheet>

最后是我使用它的错误(假设是因为$team_id没有正确设置)

#<JSON::ParserError: 203: unexpected token at 'NaN 
    }
  '>
4

2 回答 2

2

您可以定义与这些属性中的任何一个匹配的键:

<xsl:key name="id" match="@fooid | @barid" use="."/>

然后创建an_id变量 who's value is the first item from a sorted list of the attribute values,使用匹配属性值的键中的项目计数。

<xsl:variable name="an_id">
   <xsl:for-each select="*/listing/*/@*">
       <xsl:sort select="count(key('id', .))" order="descending" data-type="number"/>
       <xsl:if test="position()=1">
           <xsl:value-of select="."/>
       </xsl:if>
   </xsl:for-each>
</xsl:variable>

使用您的 XML 和 XSLT 更新答案(您几乎拥有,只需要调整您的 for-each 中的 XPath 以说明上下文节点是什么以及在评估表达式时您“站立”的位置):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" omit-xml-declaration="yes" />
    <xsl:strip-space elements="*" />

    <xsl:key name="id" match="@awayteamid | @hometeamid" use="."/>

    <xsl:template match="/message">
        <xsl:variable name="heading"><xsl:value-of select="heading"/></xsl:variable>
        <xsl:variable name="title"><xsl:value-of select="title"/></xsl:variable>
        <xsl:variable name="team_id">
            <xsl:for-each select="listing/*/@*">
                <xsl:sort select="count(key('id', .))" order="descending" data-type="number" />
                <xsl:if test="position()=1">
                    <xsl:value-of select="."/>
                </xsl:if>
            </xsl:for-each>
        </xsl:variable>

        {
        "team_id": <xsl:value-of select="number($team_id)" /> 
        }
    </xsl:template>
</xsl:stylesheet>
于 2013-09-06T02:31:12.440 回答
0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" />

<xsl:key name="kFoobars" match="foo/@fooid | bar/@fooid |
                                foo/@barid | bar/@barid" use="." />

<xsl:template match="/*">
  <xsl:variable name="foobar-els" select="*/foo | */bar" />
  <xsl:variable name="foobar-atr" select="$foobar-els/@fooid | $foobar-els/@barid" />
  <xsl:for-each select="$foobar-atr[ generate-id() =
                                     generate-id( key('kFoobars',.)[1])]">
    <xsl:sort select="count(key('kFoobars',.))" data-type="number" order="descending" />
    <xsl:if test="position()=1">
      <t most-populous-id-value="{.}" />
    </xsl:if>  
  </xsl:for-each>  
</xsl:template>

</xsl:stylesheet>
于 2013-09-06T02:47:19.837 回答