I am trying out XSLT 2.0 but I can't figure out an XPath related problem using following-sibling

huangapple go评论53阅读模式
英文:

I am trying out XSLT 2.0 but I can't figure out an XPath related problem using following-sibling

问题

Here's the translated portion of your request:

今天是:           06/08/2023
当前周期日期: 05/18/2023
下一批新图表:    06/15/2023
需要新图表。

Please note that I've translated the text within your code snippet as requested, but I haven't translated the code itself.

英文:

This code below works but I want it to display the NEXT date that the charts will be available.
My output is:
Today is: 06/08/2023
Current Cycle Date: 05/18/2023

Time for new charts.

I'm trying to get it to have another message line showing the date that the next charts will be available so it would produce an output like this:

Today is: 06/08/2023
Current Cycle Date: 05/18/2023
Next new charts: 06/15/2023
Time for new charts.

I have a commented line that would use $dtSchedNext as the variable that would be the next date but I cannot come up with a way to populate this variable with that date. I think I should use following-sibling but my XPath is not too good and I have been stuck for too long and would appreciate any help.

My command line is:
java -jar "C:\Program Files\Saxonica\SaxonJ HE 12.1\saxon-he-12.1.jar" -s:Schedule.xml -Thiscodebelow.xsl

The XML is:
Schedule.xml

  <schedule>
    <cycle>
      <date>2023-05-18-05:00</date>
      <yc>2305</yc>
      <enr>n</enr>
    </cycle>
    <cycle>
      <date>2023-06-15-05:00</date>
      <yc>2306</yc>
      <enr>y</enr>
    </cycle>
    <cycle>
      <date>2023-07-13-05:00</date>
      <yc>2307</yc>
      <enr>n</enr>
    </cycle>
    <cycle>
      <date>2023-08-10-05:00</date>
      <yc>2308</yc>
      <enr>y</enr>
    </cycle>
  </schedule>

Here is my working stylesheet though it doesn't output the needed date.

`<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                version="2.0">
  <xsl:output method="text"/>
  <xsl:variable name="docSchedule" select="document('Schedule.xml')/schedule"/>
  <!-- Returns today's date formatted as '2023-02-05-05:00'  -->
  <xsl:variable name="dtToday" as="xs:date" select="xs:date(current-date())"/>
  <!-- Opens schedule.xml,sets context to children of the root 'schedule' -->
  <!--  and returns the latest 'cycle' node only -->
  <xsl:variable name="schedCycles" select="$docSchedule/*[date < $dtToday]"/>
  <xsl:variable name="cycleLast" select="$schedCycles[position()=last()]"/>
  <!-- Extract the value of 'date' from the current cycle node -->
  <xsl:variable name="dtSched" as="xs:date" select="$cycleLast/date"/>
  <xsl:template match="/">
    <xsl:message terminate="no">Today is:
      <xsl:value-of select="format-date($dtToday,'[M01]/[D01]/[Y1]')"/>Current Cycle Date:
      <xsl:value-of select="format-date($dtSched,'[M01]/[D01]/[Y1]')"/>
      <!--  Next new charts`your text`:    <xsl:value-of select="format-date($dtSchedNext,'[M01]/[D01]/[Y1]')"/> -->
    </xsl:message>
    <xsl:choose>
      <xsl:when test="$dtToday gt $dtSched">
        <xsl:message terminate="no">
       Time for new charts.
        </xsl:message>
      </xsl:when>
      <xsl:when test="$dtToday lt $dtSched">
        <xsl:message terminate="no">
       Charts Are up to date.
        </xsl:message>
      </xsl:when>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>`

答案1

得分: 1

$cycleLast/following-sibling::cycle[1] 给出了在你选择的 $cycleLast 后面的下一个 cycle 元素。

英文:

$cycleLast/following-sibling::cycle[1] gives you the next cycle element following the one you selected in $cycleLast.

答案2

得分: 0

以下是我最终得到的内容。我必须从Marten的建议返回的字符串中提取日期数据,然后将其转换为xs:date,以便可以使用format-date()格式化它。我希望这能帮助将来的其他人,因为这对于XSLT2.0的日期处理能力来说是一项相当有趣的练习。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                version="2.0">
  <xsl:output method="text"/> 
  <xsl:variable name="docSchedule" select="document('Schedule.xml')/schedule"/>
  <!-- 返回今天的日期格式为'2023-02-05-05:00' -->
  <xsl:variable name="dtToday" as="xs:date" select="xs:date(current-date())"/>
  <!-- 打开schedule.xml,将上下文设置为根'chedule'的子节点 -->
  <!-- 并仅返回最新的'cycle'节点 -->
  <xsl:variable name="schedCycles" select="$docSchedule/*[date &lt; $dtToday]"/>
  <xsl:variable name="cycleLast" select="$schedCycles[position()=last()]"/>
  <!-- 从当前cycle节点中提取'date'的值 -->
  <xsl:variable name="dtSched" as="xs:date" select="$cycleLast/date"/>
  <xsl:variable name="cycleNext" select="substring($cycleLast/following-sibling::cycle[1],1,10)"/>
  <xsl:variable name="dtNext" select="xs:date($cycleNext)"/>
  <xsl:template match="/">
    <xsl:message terminate="no">
      今天是:              <xsl:value-of select="format-date($dtToday,'[M01]/[D01]/[Y1]')"/>
      当前周期日期:    <xsl:value-of select="format-date($dtSched,'[M01]/[D01]/[Y1]')"/>
      下一个新图表:       <xsl:value-of select="format-date($dtNext,'[M01]/[D01]/[Y1]')"/>
    </xsl:message>
    <xsl:choose>
      <xsl:when test="$dtToday gt $dtSched">
        <xsl:message terminate="no">
          是时候换新图表了。
        </xsl:message>
      </xsl:when>
      <xsl:when test="$dtToday lt $dtSched">
        <xsl:message terminate="no">
          图表已经更新。
        </xsl:message>
      </xsl:when>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

希望这对你有所帮助。

英文:

Below is what I finally ended up with. I had to extract the date data from the string that was returned by Marten's suggestion and then cast that as an xs:date so I could format it with format-date(). I hope this helps anybody else in the future as this was quite the exercise in XSLT2.0's date handling capabilities.

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;xsl:stylesheet xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;
                xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;
                version=&quot;2.0&quot;&gt;
  &lt;xsl:output method=&quot;text&quot;/&gt; 
  &lt;xsl:variable name=&quot;docSchedule&quot; select=&quot;document(&#39;Schedule.xml&#39;)/schedule&quot;/&gt;
  &lt;!-- Returns today&#39;s date formatted as &#39;2023-02-05-05:00&#39;  --&gt;
  &lt;xsl:variable name=&quot;dtToday&quot; as=&quot;xs:date&quot; select=&quot;xs:date(current-date())&quot;/&gt;
  &lt;!-- Opens schedule.xml,sets context to children of the root &#39;schedule&#39; --&gt;
  &lt;!--  and returns the latest &#39;cycle&#39; node only --&gt;
  &lt;xsl:variable name=&quot;schedCycles&quot; select=&quot;$docSchedule/*[date &amp;lt; $dtToday]&quot;/&gt;
  &lt;xsl:variable name=&quot;cycleLast&quot; select=&quot;$schedCycles[position()=last()]&quot;/&gt;
  &lt;!-- Extract the value of &#39;date&#39; from the current cycle node --&gt;
  &lt;xsl:variable name=&quot;dtSched&quot; as=&quot;xs:date&quot; select=&quot;$cycleLast/date&quot;/&gt;
  &lt;xsl:variable name=&quot;cycleNext&quot; select=&quot;substring($cycleLast/following-sibling::cycle[1],1,10)&quot;/&gt;
  &lt;xsl:variable name=&quot;dtNext&quot; select=&quot;xs:date($cycleNext)&quot;/&gt;
  &lt;xsl:template match=&quot;/&quot;&gt;
    &lt;xsl:message terminate=&quot;no&quot;&gt;
      Today is:              &lt;xsl:value-of select=&quot;format-date($dtToday,&#39;[M01]/[D01]/[Y1]&#39;)&quot;/&gt;
      Current Cycle Date:    &lt;xsl:value-of select=&quot;format-date($dtSched,&#39;[M01]/[D01]/[Y1]&#39;)&quot;/&gt;
      Next new charts:       &lt;xsl:value-of select=&quot;format-date($dtNext,&#39;[M01]/[D01]/[Y1]&#39;)&quot;/&gt;
    &lt;/xsl:message&gt;
    &lt;xsl:choose&gt;
      &lt;xsl:when test=&quot;$dtToday gt $dtSched&quot;&gt;
        &lt;xsl:message terminate=&quot;no&quot;&gt;
       Time for new charts.
        &lt;/xsl:message&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:when test=&quot;$dtToday lt $dtSched&quot;&gt;
        &lt;xsl:message terminate=&quot;no&quot;&gt;
       Charts Are up to date.
        &lt;/xsl:message&gt;
      &lt;/xsl:when&gt;
    &lt;/xsl:choose&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;

答案3

得分: 0

只需使用

(/*/cycle/date[xs:date(.) gt current-date()])[1]/string()

XSLT 2.0 - 基于验证:

这个转换:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:variable name="dtToday" as="xs:date" select="xs:date(current-date())"/>

  <xsl:template match="/*">
    <xsl:sequence select="(/*/cycle/date[xs:date(.) gt current-date()])[1]/string()"/>
  </xsl:template>
</xsl:stylesheet>

当应用于提供的 XML 文档时:

<schedule>
	<cycle>
		<date>2023-05-18-05:00</date>
		<yc>2305</yc>
		<enr>n</enr>
	</cycle>
	<cycle>
		<date>2023-06-15-05:00</date>
		<yc>2306</yc>
		<enr>y</enr>
	</cycle>
	<cycle>
		<date>2023-07-13-05:00</date>
		<yc>2307</yc>
		<enr>n</enr>
	</cycle>
	<cycle>
		<date>2023-08-10-05:00</date>
		<yc>2308</yc>
		<enr>y</enr>
	</cycle>
</schedule>

评估 XPath 表达式并输出正确的期望结果(注意,今天是 2023 年 6 月 18 日,因此正确的结果将不会与此问题中最初给出的结果相同):

2023-07-13-05:00

英文:

Just use:

(/*/cycle/date[xs:date(.) gt current-date()])[1]/string()

XSLT 2.0 - based verification:

This transformation:

&lt;xsl:stylesheet version=&quot;2.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;
 xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
 &lt;xsl:output omit-xml-declaration=&quot;yes&quot; indent=&quot;yes&quot;/&gt;
 &lt;xsl:variable name=&quot;dtToday&quot; as=&quot;xs:date&quot; select=&quot;xs:date(current-date())&quot;/&gt;

  &lt;xsl:template match=&quot;/*&quot;&gt;
    &lt;xsl:sequence select=
    &quot;(/*/cycle/date[xs:date(.) gt current-date()])[1]/string()&quot;/&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;

when applied on the provided XML document:

&lt;schedule&gt;
	&lt;cycle&gt;
		&lt;date&gt;2023-05-18-05:00&lt;/date&gt;
		&lt;yc&gt;2305&lt;/yc&gt;
		&lt;enr&gt;n&lt;/enr&gt;
	&lt;/cycle&gt;
	&lt;cycle&gt;
		&lt;date&gt;2023-06-15-05:00&lt;/date&gt;
		&lt;yc&gt;2306&lt;/yc&gt;
		&lt;enr&gt;y&lt;/enr&gt;
	&lt;/cycle&gt;
	&lt;cycle&gt;
		&lt;date&gt;2023-07-13-05:00&lt;/date&gt;
		&lt;yc&gt;2307&lt;/yc&gt;
		&lt;enr&gt;n&lt;/enr&gt;
	&lt;/cycle&gt;
	&lt;cycle&gt;
		&lt;date&gt;2023-08-10-05:00&lt;/date&gt;
		&lt;yc&gt;2308&lt;/yc&gt;
		&lt;enr&gt;y&lt;/enr&gt;
	&lt;/cycle&gt;
&lt;/schedule&gt;

Evaluates the XPath expression and outputs the correct, expected result (note that today is 6/18/2023, thus the correct result will not be the one initially stated in this problem):

2023-07-13-05:00

huangapple
  • 本文由 发表于 2023年6月9日 04:22:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76435450.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定