Xpath 查询和时间 [英] Xpath query and time

查看:91
本文介绍了Xpath 查询和时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的 XML 文件的内容:

<?xml version="1.0" encoding="ISO-8859-1"?>
<mainNode>
    <sub time="08:00">
        <status id="2">On</status>
        <status id="3">Off</status>
    </sub>
    <sub time="13:00">
        <status id="4">On</status>
        <status id="7">On</status>
    </sub>
    <sub time="16:00">
        <status id="5">On</status>
        <status id="6">On</status>
        <status id="7">Off</status>
        <status id="8">On</status>
    </sub>
    <sub time="20:00">
        <status id="4">Off</status>
        <status id="7">On</status>
    </sub>
    <sub time="23:59">
        <status id="4">On</status>
        <status id="7">On</status>
    </sub>
</mainNode>

我的程序获取当前时间:如果我得到 15.59,我必须检索下一个子时间(16.00)的所有状态 ID:

<sub time="16:00">
        <status id="5">On</status>
        <status id="6">On</status>
        <status id="7">Off</status>
        <status id="8">On</status>
    </sub>

通过第二次 XPath 查询,我必须获得前一个子时间 (13.00) 的所有状态 ID.怎么做?我知道 SQL,但我对 XPath 很陌生.我也接受严肃的 XPath 资源的 url,如果有的话.谢谢!

推荐答案

这里有两个解决方案:

这是一对 XPath 1.0 表达式,它们选择所需的节点:

This is one pair of XPath 1.0 expressions that select the required nodes:

/*/*
    [translate(@time, ':','') 
    > 
     translate('15:59',':','')
    ][1]

选择时间晚于15:59的第一个sub节点.

selects the first sub node with time later than 15:59.

/*/*
    [translate(@time, ':','') 
    < 
     translate('15:59',':','')
    ][last()]

selects 选择第一个 sub 节点早于 15:59 sub 时间.

selects selects the first sub node with the previous than 15:59 sub time.

我们可以将这些包含在 XSLT 转换中并检查是否产生了真正想要的结果:

We can include these in an XSLT transformation and check that the really wanted result is produced:

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

    <xsl:template match="/">
      First time after 15:59: 
      <xsl:copy-of select=
       "/*/*
          [translate(@time, ':','') 
         > 
           translate('15:59',':','')
          ][1]
      "/>

      First time before 15:59: 
      <xsl:copy-of select=
       "/*/*
          [translate(@time, ':','') 
         &lt; 
           translate('15:59',':','')
          ][last()]
      "/>
  </xsl:template>
</xsl:stylesheet>

当对原始提供的 XML 文档应用上述转换时:

<mainNode>
    <sub time="08:00">
        <status id="2">On</status>
        <status id="3">Off</status>
    </sub>
    <sub time="13:00">
        <status id="4">On</status>
        <status id="7">On</status>
    </sub>
    <sub time="16:00">
        <status id="5">On</status>
        <status id="6">On</status>
        <status id="7">Off</status>
        <status id="8">On</status>
    </sub>
    <sub time="20:00">
        <status id="4">Off</status>
        <status id="7">On</status>
    </sub>
    <sub time="23:59">
        <status id="4">On</status>
        <status id="7">On</status>
    </sub>
</mainNode>

产生想要的结果:

  First time after 15:59: 


<sub time="16:00">
        <status id="5">On</status>
        <status id="6">On</status>
        <status id="7">Off</status>
        <status id="8">On</status>
</sub>

  First time before 15:59: 

 <sub time="13:00">
        <status id="4">On</status>
        <status id="7">On</status>
 </sub>

请注意以下几点:

  1. XPath 的使用 translate()函数去掉冒号

last()<的使用/code> 函数在第二个表达式中

The use of the last() function in the second expression

对比前无需将时间转换为秒

当用作 XML 文档(例如 XSLT 样式表)的一部分时,< 运算符必须转义.

When used as part of an XML document (such as an XSLT stylesheet, the < operator must be escaped.

二.XPath 2.0

XPath 2.0中我们可以使用以下两个表达式 生成选择所需的节点:

II. XPath 2.0

In XPath 2.0 we can use the following two expressions to produce select the desired nodes:

/*/*[xs:time(concat(@time,':00')) 
    gt 
     xs:time('15:59:00')
    ][1]

选择时间晚于15:59的第一个sub节点.

selects the first sub node with time later than 15:59.

/*/*[xs:time(concat(@time,':00')) 
   lt 
     xs:time('15:59:00')
    ][last()]

selects 选择第一个 sub 节点早于 15:59 sub 时间.

selects selects the first sub node with the previous than 15:59 sub time.

我们可以将这些包含在 XSLT 2.0 转换中并检查是否产生了真正想要的结果:

We can include these in an XSLT 2.0 transformation and check that the really wanted result is produced:

<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"/>

    <xsl:template match="/">
      First time after 15:59: 
      <xsl:copy-of select=
       "/*/*[xs:time(concat(@time,':00')) 
           gt 
             xs:time('15:59:00')
             ][1]
      "/>

      First time before 15:59: 
      <xsl:copy-of select=
       "/*/*[xs:time(concat(@time,':00')) 
           lt 
             xs:time('15:59:00')
          ][last()]
      "/>
    </xsl:template>
</xsl:stylesheet>

当对原始提供的 XML 文档应用上述转换时(与第一个解决方案相同),会产生相同的预期结果.

When the above transformation is applied on the originally provided XML document (the same as in the first solution), the same wanted result is produced.

请注意以下几点:

  1. 在 XPath 2.0 xs:time 是本机数据类型.然而,为了从 xml 文档中的值构造一个 xs:time(),我们必须将缺少的秒部分连接到它们.
  2. 在 XPath 2.0 中,xs:time 值可以与原子值共轭运算符",例如 ltgt.
  1. In XPath 2.0 xs:time is a native data type. However, in order to construct an xs:time() from the values in the xml document, we have to concat to them the missing seconds part.
  2. In XPath 2.0 xs:time values can be compared with the "atomic-value comarison operators" such as lt or gt.

这篇关于Xpath 查询和时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆