Aqui estão duas soluções:
I. 1.0 XPath
Este é um par de XPath 1.0 expressões que selecionam os nós necessários:
/*/*
[translate(@time, ':','')
>
translate('15:59',':','')
][1]
selecciona o primeiro subnó com o tempo mais tarde do que 15:59.
/*/*
[translate(@time, ':','')
<
translate('15:59',':','')
][last()]
selecciona selecciona o primeiro subnó com o anterior de 15:59 subtempo .
Podemos incluir estes em uma transformação XSLT e verificar que o resultado realmente queria é produzido:
<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, ':','')
<
translate('15:59',':','')
][last()]
"/>
</xsl:template>
</xsl:stylesheet>
Quando a transformação acima é aplicado sobre o documento XML fornecido originalmente:
<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>
o resultado desejado é produzido :
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>
Observe o seguinte:
O uso da XPath translate()função para se livrar dos dois pontos
A utilização da last()função no segundo expressão
Não há necessidade de converter o tempo para segundos antes da comparação
Quando usado como parte de um documento XML (como uma folha de estilo XSLT, o <operador deve ser escapado .
II. XPath 2.0
Em XPath 2.0 , podemos usar as duas expressões a seguir para produzir selecione os nós desejados:
/*/*[xs:time(concat(@time,':00'))
gt
xs:time('15:59:00')
][1]
selecciona o primeiro subnó com o tempo mais tarde do que 15:59.
/*/*[xs:time(concat(@time,':00'))
lt
xs:time('15:59:00')
][last()]
selecciona selecciona o primeiro subnó com o anterior de 15:59 subtempo .
Podemos incluir estes em uma transformação XSLT 2.0 e verificar que o resultado realmente queria é produzido:
<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>
Quando a transformação acima é aplicada sobre o documento XML originalmente fornecida (o mesmo que na primeira solução), o mesmo resultado desejado é produzido.
Observe o seguinte:
- Em XPath 2,0
xs:timeé um tipo de dados nativa . No entanto, a fim de construir um xs:time()dos valores no documento XML, temos que concat a eles a parte que falta segundos.
- Em XPath 2.0
xs:timevalores podem ser comparados com os " operadores comarison de valor atómica " tal como ltou gt.