通过XSL访问多个XML文件

时间:2015-09-25 05:45:43

标签: xml xslt

我目前正在尝试从多个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>

我在尝试加载此XSL表样式的相应Rainfall.xml文件时,目前正在从浏览器获得不响应。

有人可以指出我正确的方向吗?此外,如果有人可以向我推荐一些有关使用XSL表格来创建和格式化XML文件的信息,那么我们将非常感激。

1 个答案:

答案 0 :(得分:0)

以下方法可行(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。相应地调整它们。