2012-09-20 19 views
8

-Teniendo en cuenta esta pieza de XMLXSL si la prueba se inicia con

<dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date> 
<dc:date>2012-07-04</dc:date> 

debería necesitar con XSL para emitir sólo el año de la cadena que no empiezan coninfo:eu-repo. Lo intento de esta manera, pero no funciona. Estoy equivocado con el for-each?

<xsl:if test="not(starts-with('dc:date', 'info:eu-repo'))"> 
       <xsl:for-each select="dc:date"> 
        <publicationYear> 
         <xsl:variable name="date" select="."/> 
         <xsl:value-of select="substring($date, 0, 5)"/> 
        </publicationYear> 
       </xsl:for-each> 
</xsl:if> 

Respuesta

16

supongo que no es necesario ' en su consulta start-with, y es posible que desee iterar sobre las fechas de forma ligeramente diferente:

<xsl:for-each select="dc:date"> 
     <xsl:variable name="date" select="."/> 
     <xsl:if test="not(starts-with($date, 'info:eu-repo'))"> 
       <publicationYear> 
        <xsl:value-of select="substring($date, 0, 5)"/> 
       </publicationYear> 
     </xsl:if> 
    </xsl:for-each> 
+0

intenté sin 'pero no funciona. el resultado que obtuve 2012 información

+0

He editado mi respuesta. Parece que tienes un problema de iteración también. – DRCB

+0

gracias, lástima de mí, puse la prueba fuera de la iteración –

1

También podría utilizar un template-match para conseguir lo que quiere, por ejemplo:

<xsl:template match="date[not(starts-with(.,'info:eu-repo'))]"> 
    <xsl:value-of select="."/> 
</xsl:template> 

tengo este XML de entrada:

<?xml version="1.0" encoding="UTF-8"?> 
<list> 
<date>info:eu-repo/date/embargoEnd/2013-06-12</date> 
<date>2012-07-04</date> 
</list> 

y aplicar esta XSLT a ella:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
<xsl:template match="text() | @*"/> 

<xsl:template match="/"> 
    <xsl:apply-templates /> 
</xsl:template> 

<xsl:template match="date[not(starts-with(.,'info:eu-repo'))]"> 
    <xsl:value-of select="."/> 
</xsl:template> 

</xsl:stylesheet> 

y me da este resultado:

<?xml version="1.0" encoding="UTF-8"?>2012-07-04 

Saludos, Peter

1

Uso (suponiendo que el fragmento de XML proporcionado es elementos que son secundarios del nodo actual y solo hay un elemento con la propiedad deseada):

substring-before(*[not(starts-with(., 'info:eu-repo'))], '-') 

XSLT - verificación basada:

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

<xsl:template match="/*"> 
    <xsl:copy-of select= 
    "substring-before(*[not(starts-with(., 'info:eu-repo'))], '-') "/> 
</xsl:template> 
</xsl:stylesheet> 

Cuando se aplica esta transformación para el siguiente documento XML (el fragmento proporcionado envuelto en un elemento superior solo y el espacio de nombres declarado):

<t xmlns:dc="some:dc"> 
    <dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date> 
    <dc:date>2012-07-04</dc:date> 
</t> 

La expresión XPath se evalúa desde el elemento superior y el re sultado de esta evaluación se copia a la salida:

2012 

II. Más de un elemento con la propiedad deseada:

En este caso No es posible generar los datos deseados con una única expresión XPath 1.0.

Esta transformación XSLT:

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

<xsl:template match="*[not(starts-with(., 'info:eu-repo'))]/text()"> 
    <xsl:copy-of select="substring-before(., '-') "/> 
============== 
</xsl:template> 
<xsl:template match="text()"/> 
</xsl:stylesheet> 

cuando se aplica en este documento XML:

<t xmlns:dc="some:dc"> 
    <dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date> 
    <dc:date>2012-07-04</dc:date> 
    <dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date> 
    <dc:date>2011-07-05</dc:date> 
</t> 

produce el, resultado correcto deseada:

2012 
============== 
2011 
============== 

III. XPath 2.0 de una sola línea

*[not(starts-with(., 'info:eu-repo'))]/substring-before(., '-') 

Cuando esto XPath 2.0 expresión se evalúa fuera el elemento superior del anterior documento de XML (el más cercano arriba), los años deseados se producen:

2012 2011 

XSLT 2.0 - basado en la verificación:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/*"> 
    <xsl:sequence select= 
    "*[not(starts-with(., 'info:eu-repo'))]/substring-before(., '-')"/> 
</xsl:template> 
</xsl:stylesheet> 

Cuando se aplica esta transformación en el último documento XML, la expresión XPath se evalúa y el resultado de esta evaluación se copia a la salida:

2012 2011 

IV. El caso más general y difícil:

Ahora, vamos a tener este documento XML:

<t xmlns:dc="some:dc"> 
    <dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date> 
    <dc:date>2012-07-04</dc:date> 
    <dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date> 
    <dc:date>2011-07-05</dc:date> 
    <dc:date>*/date/embargoEnd/2014-06-12</dc:date> 
</t> 

Todavía queremos obtener la parte del año de todos los dc:date elementos cuyo valor de cadena no comienza con 'información: eu-repo '. Sin embargo, ninguna de las soluciones anteriores funciona correctamente con el último elemento dc:date anterior.

Sorprendentemente, los datos deseados pueden todavía ser producido por un solo XPath 2.0 expresión:

for $s in 
     *[not(starts-with(., 'info:eu-repo'))]/tokenize(.,'/')[last()] 
    return 
     substring-before($s, '-') 

Cuando esta expresión se evalúa fuera el elemento superior del documento XML anterior, el, resultado correcto deseado se produce:

2012 2011 2014 

Y este es el XSLT 2.0 - la verificación basada:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/*"> 
    <xsl:sequence select= 
    "for $s in 
     *[not(starts-with(., 'info:eu-repo'))]/tokenize(.,'/')[last()] 
    return 
     substring-before($s, '-') 
    "/> 
</xsl:template> 
</xsl:stylesheet> 
Cuestiones relacionadas