我有一些难以处理的标记,它没有标准化的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
已知要点如下:
我正在使用XSLT 1.0。变量名称不是动态的。它是静态的,只要它导出的值是上面的81就可以称为whatever
。
**更新**
我上面粘贴的XML是样本,虽然我认为Mads的答案是正确的,但它没有解析,所以我用我正在处理的真实XML进行更新。您可以在我的设计示例中看到<foo>
和<bar>
正在尝试处理<hometeam>
和<awayteam>
标记的等效内容,这些标记是关注的重点。< / p>
<?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&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为“081”,但是一旦在XSLT处理器上运行number()
,它就应该是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
}
'>
答案 0 :(得分:2)
您可以定义与其中任何一个属性匹配的键:
<xsl:key name="id" match="@fooid | @barid" use="."/>
然后创建an_id
变量,其值是属性值排序列表中的第一项,使用与属性值匹配的项中的项目数。
<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以考虑上下文节点是什么以及在表达式得到评估时“站立”的位置):< / p>
<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>
答案 1 :(得分: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>