XSLT基于属性迭代兄弟姐妹

时间:2013-02-27 08:42:24

标签: xml xslt adobe-indesign

我正在尝试通过XSLT将XML数据导入Adobe InDesign。 InDesign似乎无法使用属性,即使它可以看到属性。

我可以使用以下格式访问免费天气数据:http://www.yr.no/sted/Norge/Oslo/Oslo/Oslo/varsel.xml

我不确定我将XSLT转换为常规XML格式的方式是最好的,但它是否有效。

我遇到的问题是我需要明天的天气数据,但我只获取今天的数据。 数据存储在weatherdata / forecast / tabular / time中。

我使用<xsl:param name="speedmps" select="weatherdata/forecast/tabular/time[@period='2']/windSpeed/@mps" />来选择数据,但这只会选择第一个匹配项。 第一场比赛是今天的天气(从12:00到18:00),我想要的是第二场比赛(第二场比赛='2'比赛,即明天12:00至18:00)。 这一天以4个周期呈现,XML文件获得了几天的预测。理想情况下,我想为今天的天气制作一个XSLT,一个用于明天的天气等等。

我的代码主要是剪切和粘贴,然后我尝试编辑它以执行我想要的操作。 我尝试制作一个if块,但是我找不到任何可以构建的例子。我目前在XSLT方面的技能太基础了,而且我的截止日期很短。 我在源数据中发现的是,周期根据您获取数据的时间而变化。 所以我不能说它应该选择第6个区块,因为明天周期='2'可能是当天这个时间的第5个。 (句号='0'为00:00至09:00,因此在09:00之后0期将被删除,依此类推。)

现在的第一场比赛是:

<time from="2013-02-27T12:00:00" to="2013-02-27T18:00:00" period="2">
    <!-- Valid from 2013-02-27T12:00:00 to 2013-02-27T18:00:00 -->
    <symbol number="1" name="Klarvær" var="01d" />
    <precipitation value="0" />
    <!-- Valid at 2013-02-27T12:00:00 -->
    <windDirection deg="187.2" code="S" name="Sør" />
    <windSpeed mps="1.5" name="Flau vind" />
    <temperature unit="celsius" value="-1" />
    <pressure unit="hPa" value="1030.2" />
  </time>    

现在的第二场比赛是:

<time from="2013-02-28T12:00:00" to="2013-02-28T18:00:00" period="2">
    <!-- Valid from 2013-02-28T12:00:00 to 2013-02-28T18:00:00 -->
    <symbol number="1" name="Klarvær" var="01d" />
    <precipitation value="0" />
    <!-- Valid at 2013-02-28T12:00:00 -->
    <windDirection deg="181.3" code="S" name="Sør" />
    <windSpeed mps="3.1" name="Svak vind" />
    <temperature unit="celsius" value="2" />
    <pressure unit="hPa" value="1015.7" />
  </time>

我很抱歉,但英语不是我的第一语言,我尽力解释。

这是我的XSLT代码:

    <?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes" omit-xml-declaration="no" cdata-section-elements="" />

<!-- params -->
<xsl:param name="location" select="weatherdata/location/name"/>
<xsl:param name="alternate" select="weatherdata/links/link[@id='overview']/@url"/>
<xsl:param name="base" select="'file:///d:/temp/yr/sky/'"/>
<!-- We use the text forecast dates or? -->
<xsl:param name="lastupdate" select="weatherdata/meta/lastupdate" />
<xsl:param name="symbolnumber" select="weatherdata/forecast/tabular/time[@period='2']/symbol/@number" />
<xsl:param name="symbolname" select="weatherdata/forecast/tabular/time[@period='2']/symbol/@name" />
<xsl:param name="symbolvar" select="weatherdata/forecast/tabular/time[@period='2']/symbol/@var" />
<xsl:param name="precip" select="weatherdata/forecast/tabular/time[@period='2']/precipitation/@value" />
<xsl:param name="directiondeg" select="weatherdata/forecast/tabular/time[@period='2']/windDirection/@deg" />
<xsl:param name="directioncode" select="weatherdata/forecast/tabular/time[@period='2']/windDirection/@code" />
<xsl:param name="directionname" select="weatherdata/forecast/tabular/time[@period='2']/windDirection/@name" />
<xsl:param name="speedmps" select="weatherdata/forecast/tabular/time[@period='2']/windSpeed/@mps" />
<xsl:param name="speedname" select="weatherdata/forecast/tabular/time[@period='2']/windSpeed/@name" />
<xsl:param name="tempvalue" select="weatherdata/forecast/tabular/time[@period='2']/temperature/@value" />

<xsl:template match="/">
<yr>
<testtag>   
    <title><xsl:value-of select="$location"/></title>
    <alternate><xsl:value-of select="$alternate"/></alternate>
    <base><xsl:value-of select="$base"/></base>
    <lastupdate><xsl:value-of select="$lastupdate"/></lastupdate>
    <symbolvar><xsl:value-of select="$symbolvar"/></symbolvar>
    <symbolnr><xsl:value-of select="$symbolnumber"/></symbolnr>
    <symbolname><xsl:value-of select="$symbolname"/></symbolname>
    <precip><xsl:value-of select="$precip"/></precip>
    <tempval><xsl:value-of select="$tempvalue"/></tempval>
    <speedname><xsl:value-of select="$speedname"/></speedname>
    <speedmps><xsl:value-of select="$speedmps"/></speedmps>
    <dirdeg><xsl:value-of select="$directiondeg"/></dirdeg>
    <dircode><xsl:value-of select="$directioncode"/></dircode>
    <dirname><xsl:value-of select="$directionname"/></dirname>
    <Image><xsl:attribute name="href"><xsl:value-of select="$base"/><xsl:value-of select="$symbolvar"/>.png</xsl:attribute></Image>
</testtag>  
</yr>
</xsl:template> 

</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

如果您想要第二个time[@period = '2']元素(换句话说,如果我理解正确的话),您可以使用time[@period='2'][2]

但是,你的样式表并不是真正的XSLT方式。除了将节点值存储在<xsl:param>元素中然后再处理它们之外,这个惯例是 - 而且我在这里简化了很多 - 显然 - 为输入文档中的每个节点都有一个<xsl:template>元素你想要处理。

有很多方法可以实现您的目标,但您可以使用下面的样式表作为代码的起点。

输入

<time>属性值为@period的第二个2

<time from="2013-02-28T12:00:00" to="2013-02-28T18:00:00" period="2">
    <!-- Valid from 2013-02-28T12:00:00 to 2013-02-28T18:00:00 -->
    <symbol number="1" name="Klarvær" var="01d" />
    <precipitation value="0" />
    <!-- Valid at 2013-02-28T12:00:00 -->
    <windDirection deg="181.3" code="S" name="Sør" />
    <windSpeed mps="3.1" name="Svak vind" />
    <temperature unit="celsius" value="2" />
    <pressure unit="hPa" value="1015.7" />
</time>

样式表

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" encoding="ISO-8859-1" indent="yes" omit-xml-declaration="no" cdata-section-elements=""/>
  <xsl:strip-space elements="*"/>

  <!--
  The position of the time[@period = '2'] element; indexing starts from 1.
  You can pass in this parameter to the transformation if you want the
  time[@period = '2'] element in some other position.
  -->
  <xsl:param name="time" select="2"/>
  <xsl:param name="base" select="'file:///d:/temp/yr/sky/'"/>

  <xsl:template match="/">
    <yr>
      <testtag>
        <xsl:apply-templates select="weatherdata"/>
      </testtag>
    </yr>
  </xsl:template>

  <xsl:template match="weatherdata">
    <xsl:apply-templates select="location/name"/>
    <xsl:apply-templates select="links/link[@id = 'overview']"/>
    <base><xsl:value-of select="$base"/></base>
    <xsl:apply-templates select="meta/lastupdate"/>
    <!-- Apply the <time period="2"> element in $time position -->
    <xsl:apply-templates select="forecast/tabular/time[@period = '2'][number($time)]"/>
  </xsl:template>

  <xsl:template match="tabular/time">
    <xsl:apply-templates select="symbol"/>
    <xsl:apply-templates select="precipitation"/>
    <xsl:apply-templates select="temperature"/>
    <xsl:apply-templates select="windSpeed"/>
    <xsl:apply-templates select="windDirection"/>

    <!--
    Use attribute value template (AVT) to construct the attribute value:
    http://lenzconsulting.com/how-xslt-works/#attribute_value_templates
    -->
    <Image href="{concat($base, symbol/@var, '.png')}"/>
  </xsl:template>

  <xsl:template match="location/name">
    <title>
      <xsl:value-of select="."/>
    </title>
  </xsl:template>

  <xsl:template match="links/link">
    <alternate>
      <!-- Use the value of the @url attribute of this element -->
      <xsl:value-of select="@url"/>
    </alternate>
  </xsl:template>

  <xsl:template match="temperature">
    <tempval>
      <xsl:value-of select="@value"/>
    </tempval>
  </xsl:template>

  <xsl:template match="windSpeed">
    <speedname>
      <xsl:value-of select="@name"/>
    </speedname>

    <speedmps>
      <xsl:value-of select="@mps"/>
    </speedmps>
  </xsl:template>

  <xsl:template match="windDirection">
    <dirdeg>
      <xsl:value-of select="@deg"/>
    </dirdeg>

    <dircode>
      <xsl:value-of select="@code"/>
    </dircode>

    <dirname>
      <xsl:value-of select="@name"/>
    </dirname>
  </xsl:template>

  <xsl:template match="precipitation">
    <precip>
      <xsl:value-of select="@value"/>
    </precip>
  </xsl:template>

  <xsl:template match="symbol">
    <symbolvar>
      <xsl:value-of select="@var"/>
    </symbolvar>

    <symbolnr>
      <xsl:value-of select="@number"/>
    </symbolnr>

    <symbolname>
      <xsl:value-of select="@name"/>
    </symbolname>
  </xsl:template>

  <xsl:template match="lastupdate">
    <!-- Copy the original node as is -->
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

输出

<?xml version="1.0" encoding="ISO-8859-1"?>
<yr>
  <testtag>
    <title>Oslo</title>
    <alternate>http://www.yr.no/sted/Norge/Oslo/Oslo/Oslo/</alternate>
    <base>file:///d:/temp/yr/sky/</base>
    <lastupdate>2013-02-27T06:39:00</lastupdate>
    <symbolvar>01d</symbolvar>
    <symbolnr>1</symbolnr>
    <symbolname>Klarv?r</symbolname>
    <precip>0</precip>
    <tempval>2</tempval>
    <speedname>Svak vind</speedname>
    <speedmps>3.1</speedmps>
    <dirdeg>181.3</dirdeg>
    <dircode>S</dircode>
    <dirname>S?r</dirname>
    <Image href="file:///d:/temp/yr/sky/01d.png"/>
  </testtag>
</yr>