XSLT document()函数与for循环表格无法正常工作问题求助
解决XSLT中document()函数与表格遍历的问题
嘿,我来帮你搞定这个作业里的问题!你说要做一个weather.xsl来展示两个XML气象文件的数据,但卡在了document()函数和表格循环上,咱们一步步拆解解决。
首先,先确认你提供的IDN10031.xml结构(我帮你格式化好了):
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="weather-1.xsl"?> <product version="1.7" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.bom.gov.au/schema/v1.7/product.xsd"> <amoc> <source> <sender>Australian Government Bureau of Meteorology</sender> <region>New South Wales</region> <office>NSWRO</office> <copyright>http://www.bom.gov.au/other/copyright.shtml</copyright> <disclaimer>http://www.bom.gov.au/other/disclaimer.shtml</disclaimer> </source> <identifier>IDN10031</identifier> <issue-time-utc>2018-04-25T18:30:00Z</issue-time-utc> <issue-time-local tz="EST">2018-04-26T04:30:00+10:00</issue-time-local> <sent-time>2018-04-25T18:30:03Z</sent-time> <expiry-time>2018-05-05T18:30:00Z</expiry-time> <validity-bgn-time-local tz="EST">2018-04-26T04:30:02+10:00</validity-bgn-time-local> <validity-end-time-local tz="EST">2018-04-29T23:59:59+10:00</validity-end-time-local> <next-routine-issue-time-utc>2018-04-26T06:30:00Z</next-routine-issue-time-utc> <next-routine-issue-time-local tz="EST">2018-04-26T16:30:00+10:00</next-routine-issue-time-local> <status>O</status> <service>WSP</service> <sub-service>FST</sub-service> <product-type>F</product-type> <phase>NEW</phase> </amoc> <forecast> <area aac="NSW_FA001" description="New South Wales" type="region"> <forecast-period start-time-local="2018-04-26T04:30:02+10:00" end-time-local="2018-04-26T04:30:02+10:00" start-time-utc="2018-04-25T18:30:02Z" end-time-utc="2018-04-25T18:30:02Z"> <text type="synoptic_situation"> <p>A low pressure trough off the New South Wales north coast is weakening as a high pressure system south of the Bight moves very slowly east extending a ridge along the coast. The high is expected to move over the southern Tasman by Wednesday maintaining the ridge to the north.</p> </text> <text type="warning_summary_footer">Details of warnings are available on the Bureau's website www.bom.gov.au, by telephone 1300-659-218* or through some TV and radio broadcasts.</text> <text type="product_footer">* Calls to 1300 numbers cost around 27.5c incl. GST, higher from mobiles or public phones.</text> </forecast-period> <forecast-period index="0" start-time-local="2018-04-26T05:00:00+10:00" end-time-local="2018-04-27T00:00:00+10:00" start-time-utc="2018-04-25T19:00:00Z" end-time-utc="2018-04-26T14:00:00Z"> <text type="fire_danger">Very High: Northwestern fire area.</text> <text type="forecast">Medium chance of showers along the northern half of the coast with the risk of thunderstorms. The chance of afternoon thunderstorms in the northern inland. Early fog in the east. Partly cloudy elsewhere. Daytime temperatures close to average. Winds south to southwesterly, freshening along the coast and about the central west slopes.</text> </forecast-period> <forecast-period index="1" start-time-local="2018-04-27T00:00:00+10:00" end-time-local="2018-04-28T00:00:00+10:00" start-time-utc="2018-04-26T14:00:00Z" end-time-utc="2018-04-27T14:00:00Z"> <text type="forecast">A shower or two in the east, more likely about the north coast. The chance of a thunderstorm in the far northeast. Early frost patches about the southern ranges. Fine and mostly sunny in the west. Daytime temperatures below average, especially in the southeast. South to southeasterly winds, freshening about the northeast and along the coast.</text> </forecast-period> <forecast-period index="2" start-time-local="2018-04-28T00:00:00+10:00" end-time-local="2018-04-29T00:00:00+10:00" start-time-utc="2018-04-27T14:00:00Z" end-time-utc="2018-04-28T14:00:00Z"> <text type="forecast">Showers in the east, more likely about the central and northern coastal fringe. Fine and mostly sunny elsewhere. Early frost patches about the southern ranges. Daytime temperatures below average in the east and about average elsewhere. South to southeasterly winds, freshening about the north coast.</text> </forecast-period> <forecast-period index="3" start-time-local="2018-04-29T00:00:00+10:00" end-time-local="2018-04-30T00:00:00+10:00" start-time-utc="2018-04-28T14:00:00Z" end-time-utc="2018-04-29T14:00:00Z"> <text type="forecast">Showers in the</text> </forecast-period> </area> </forecast> </product>
常见问题排查与解决方案
1. document()函数失效的原因
- 文件路径错误:确保
IDN10031.xml、IDN11032.xml和weather.xsl在同一目录下,或者用正确的相对路径(比如document('./xml/IDN10031.xml')如果XML在子目录)。 - 浏览器本地文件限制:Chrome等现代浏览器会阻止本地XML文件加载其他本地文件(跨域限制),解决办法是用本地服务器运行,比如:
- 打开终端,进入文件目录,运行
python -m http.server 8000(Python3) - 然后访问
http://localhost:8000/IDN10031.xml
- 打开终端,进入文件目录,运行
- 命名空间问题:如果另一个XML有命名空间,你需要在XSL里声明命名空间并在节点选择时使用前缀(不过你的示例XML没有命名空间,这个暂时不用考虑)。
2. 表格循环(for-each)不工作的问题
大概率是节点选择路径错误,比如你可能没精准定位到forecast-period节点。下面给你一个完整的weather.xsl示例,同时处理两个XML文件并生成表格:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes"/> <xsl:template match="/"> <html> <head> <title>Weather Forecast Summary</title> <style> .forecast-table { border-collapse: collapse; width: 90%; margin: 15px auto; } .forecast-table th, .forecast-table td { border: 1px solid #ccc; padding: 10px; text-align: left; } .forecast-table th { background-color: #f5f5f5; font-weight: bold; } .region-title { text-align: center; color: #2c3e50; } </style> </head> <body> <h1 style="text-align: center;">Australian Bureau of Meteorology Forecasts</h1> <!-- 处理第一个XML文件 --> <div> <h2 class="region-title">IDN10031 - New South Wales</h2> <xsl:for-each select="document('IDN10031.xml')/product/forecast/area/forecast-period[@index]"> <table class="forecast-table"> <tr> <th>Period Index</th> <td><xsl:value-of select="@index"/></td> </tr> <tr> <th>Date Range (Local)</th> <td><xsl:value-of select="substring(@start-time-local, 1, 10)"/> to <xsl:value-of select="substring(@end-time-local, 1, 10)"/></td> </tr> <tr> <th>Forecast</th> <td><xsl:value-of select="text[@type='forecast']"/></td> </tr> <!-- 可选:显示火险等级(如果存在) --> <xsl:if test="text[@type='fire_danger']"> <tr> <th>Fire Danger</th> <td><xsl:value-of select="text[@type='fire_danger']"/></td> </tr> </xsl:if> </table> </xsl:for-each> </div> <!-- 处理第二个XML文件 --> <div> <h2 class="region-title">IDN11032 Forecast</h2> <xsl:for-each select="document('IDN11032.xml')/product/forecast/area/forecast-period[@index]"> <table class="forecast-table"> <tr> <th>Period Index</th> <td><xsl:value-of select="@index"/></td> </tr> <tr> <th>Date Range (Local)</th> <td><xsl:value-of select="substring(@start-time-local, 1, 10)"/> to <xsl:value-of select="substring(@end-time-local, 1, 10)"/></td> </tr> <tr> <th>Forecast</th> <td><xsl:value-of select="text[@type='forecast']"/></td> </tr> <xsl:if test="text[@type='fire_danger']"> <tr> <th>Fire Danger</th> <td><xsl:value-of select="text[@type='fire_danger']"/></td> </tr> </xsl:if> </table> </xsl:for-each> </div> </body> </html> </xsl:template> </xsl:stylesheet>
关键注意点
- 用
forecast-period[@index]过滤掉没有index属性的初始时段(那个包含天气形势概述的节点),只展示每日预报。 - 如果
IDN11032.xml的结构和IDN10031.xml略有不同,你需要调整for-each里的节点路径,比如如果它的area节点有不同的属性,要确保选择正确。 - 测试时一定要用本地服务器,避免浏览器的本地文件限制导致
document()加载失败。
内容的提问来源于stack exchange,提问作者Ovaflow
相关产品推荐
相关产品推荐

