通过XSL访问多个XML文件

3

我目前正在尝试访问多个XML文件中的数据。我已经轻松地从第一个名为Rainfall.xml的文件中访问了数据,但是无法从我的列表中的下一个文件Max_temp.xml检索任何数据。

总体目标是将4-5个XML文件合并在一起,包括有关各种天气事件以及记录这些事件的站点的所有数据。

以下是示例代码:

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

    <!-- TODO customize transformation rules 
         syntax recommendation http://www.w3.org/TR/xslt 
    -->
<xsl:variable name="maxTemp" select="document('Max_temp.xml')" />  

<xsl:template match="rainfall">
&lt;weather&gt;
      <xsl:apply-templates select="measurement" />
&lt;/weather&gt;

</xsl:template>


<xsl:template match="measurement">
    &lt;measurement&gt;
        &lt;StationNum&gt;<xsl:value-of select="StationNum"/>&lt;/StationNum&gt;
        &lt;Date&gt;<xsl:value-of select="concat(Day,'/',Month,'/',Year)"/>&lt;/Date&gt;
        <xsl:variable name="Date" select="concat(Day,'/',Month'/',Year)"/>
        &lt;Rainfall&gt;<xsl:value-of select="Volume"/>&lt;/Rainfall&gt;
        &lt;MaxTemp&gt;<xsl:value-of select="$MaxTemp/maxTemp/measurement[concat(Day,'/',Month'/',Year)].equals(Date)"/>&lt;/MaxTemp&gt;
    &lt;/measurement&gt;
</xsl:template>

</xsl:stylesheet>

正在使用的XML文件的结构如下所示:
<typeOfFile(Rainfall, Temp, Solar Radiation etc)>
    <measurment>
        <Code>...</Code>
        <Station>...</Station>
        <Day>...</Day>
        <Month>...</Month>
        <Year>...</Year>
        <Volume>...</Volume>
    </measurement>
</typeOfFile>

当我尝试加载相应的Rainfall.xml文件并使用此XSL样式表进行格式化时,浏览器没有响应。

请问有人能指点我正确的方向吗?如果有人能提供关于如何使用XSL样式表创建和格式化XML文件的信息,将不胜感激。


&lt;weather&gt;&lt;measurement&gt;等标签的目的是什么?输出标签吗?更多使用变量 $MaxTemp,但你声明的是 maxTemp - XSLT是大小写敏感的。 - potame
1个回答

4
以下方法可行(XSLT 1.0):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml"/>

    <!-- select the <measurement> elements of all the various input files -->
    <xsl:variable name="maxTemp" select="document('Max_temp.xml')/*" />
    <xsl:variable name="rainfall" select="document('rainfall.xml')/*" />
    <xsl:variable name="solarRadiation" select="document('solar_radiation.xml')/*" />

    <!-- index <measurement> elements by their station and date -->
    <xsl:key name="kMeasurement" match="measurement"
        use="concat(Station, '/', Day, '/', Month, '/', Year)"
    />

    <xsl:template match="/">
        <weather>
            <xsl:apply-templates select="$maxTemp/measurement" />
        </weather>
    </xsl:template>

    <xsl:template match="measurement">
        <xsl:variable name="currentKey" select="concat(Station, '/', Day, '/', Month, '/', Year)" />

        <measurement>
            <StationNum><xsl:value-of select="Station"/></StationNum>
            <Date><xsl:value-of select="concat(Day, '/', Month, '/', Year)"/></Date>

            <!-- since we are handling maxTemp measurements here, we can output that directly -->
            <MaxTemp><xsl:value-of select="Value"/></MaxTemp>

            <!-- to access the others we need a context switch and a key lookup -->
            <xsl:for-each select="$rainfall">
                <Rainfall><xsl:value-of select="key('kMeasurement', $currentKey)/Volume"/></Rainfall>
            </xsl:for-each>
            <xsl:for-each select="$solarRadiation">
                <SolarRadiation><xsl:value-of select="key('kMeasurement', $currentKey)/Watt"/></SolarRadiation>
            </xsl:for-each>
            <!-- and so on -->
        </measurement>
    </xsl:template>
</xsl:stylesheet>

您需要将其应用于一个空的虚拟输入文档(类似于简单的<xml />)。

然后,它会将所有实际文件加载到变量中,并按照其中一个文件中的条目创建输出。我选择了最高温度测量值,但是如果所有文件都包含相同日期的数据点,则不会有任何影响。

这些最高温度数据点中的每一个都会生成一个输出<measurement>元素。

为此,它使用<xsl:key>从相关文档中提取正确的测量值。 <xsl:key>是一个键/值存储(即字典,哈希表):它通过某个关键字符串对节点进行索引,在我们的情况下是站点ID和日期的组合。

但是,它仅返回与当前节点位于同一文档中的节点。因此,要输出Max_temp.xml之外的任何内容,我们必须将上下文切换到另一个文档。 <xsl:for-each>可以做到这一点,因此我们在这里使用它来设置我们调用key()的范围($rainfall$solarRadiation只持有单个元素)。

请注意,由于我必须猜测您的实际输入文档结构,因此一些XPath可能不准确。请相应地进行调整。


非常感谢,这帮了我大忙了,现在它已经按照我的要求运行了。接下来,我该如何将其写入一个名为“weather.xml”的新文件中?我猜这可能与document()函数有关? - Rory Perry
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Tomalak
1
啊哈!我现在明白了,谢谢你。之前没太明白我需要保存它才能将其输出为XML。现在只需要格式化它 :) - Rory Perry
想知道你是否能帮我解决如何创建一个文件共享不同结构的键的问题?我接下来要处理的文件是一个站点文件,格式如下: <stations> <station> <site>1000</site> <name>Karunjie</name> <latitude>16.29</latitude> <longitude>127.2</longitude> <state>WA</state> </station> </stations>我需要获取特定站点的数据,并将其作为我的<weather>元素的属性。 - Rory Perry
更多地看待它,使用谓词来匹配它,就像这样:.station[site = '081123']。 - Rory Perry
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接