2012-09-20 14 views
8

Biorąc pod uwagę ten kawałek XMLXSL Jeśli test starts-with

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

powinny muszę z XSL do wyjścia tylko rok napisu nie wychodząc zinfo:eu-repo. Próbuję w ten sposób, ale to nie działa. Myliłem się z 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> 

Odpowiedz

16

Chyba nie trzeba ' w zapytaniu start-with, a może chcesz iteracyjne nad dat nieco inaczej:

<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

Próbowałem bez "ale nie działa. wynik otrzymałem 2012 /

+0

Edytowałem swoją odpowiedź. Wygląda na to, że masz również problem z iteracją. – DRCB

+0

dziękuję, wstydź mi, wystawiam test poza iterację –

1

Można również użyć template-match aby uzyskać to, co chcesz, na przykład:

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

mam ten XML wejściowego:

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

i zastosować tę XSLT do niej:

<?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> 

i uzyskać ten wynik:

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

poważaniem, Peter

1

Zastosowanie (zakładając dostarczony fragment XML elementy, które są elementami podrzędnymi bieżącego węzła i jest tylko jeden element o pożądanej właściwości):

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

XSLT - na podstawie weryfikacji:

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

Kiedy transformacja ta jest stosowana do poniższego dokumentu XML (dostarczonego fragmentu zawinięte w jednym górnego elementu i nazw zadeklarowanej):

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

Wyrażenie XPath jest oceniane od górnego elementu i od końca DOPROWADZIĆ tej oceny jest kopiowany do wyjścia:

2012 

II. Więcej niż jeden element o pożądanej właściwości:

W tym przypadku nie można utworzyć żądanych danych za pomocą jednego wyrażenia XPath 1.0.

Ta transformacja 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> 

po nałożeniu na tego dokumentu 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> 

produkuje Wanted, poprawny wynik:

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

III. XPath 2.0 jedno-liner

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

Gdy XPath wyrażenie 2,0 ocenia się górny element dokumentu ostatni XML (najbliższy powyżej), The Wanted lat produkowane są:

2012 2011 

XSLT 2.0 - na podstawie weryfikacji:

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

Gdy ta transformacja jest stosowany w ostatnim dokumencie XML, wyrażenie XPath jest oceniane, a wynik tej oceny jest kopiowany do wyjścia:

2012 2011 

IV. Sprawa najogólniejszym i trudne:

Teraz, zjedzmy tego dokumentu 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> 

Nadal chcesz uzyskać letnią część wszystkich dc:date elementów, których wartość ciągu nie uruchamia się z „informacją: eu-repo ". Jednak żadne z poprzednich rozwiązań nie działa poprawnie z ostatnim elementem dc:date powyżej.

Co ciekawe, dane poszukiwanych wciąż mogą być produkowane przez jednego XPath 2.0 ekspresji:

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

Gdy ta ekspresja jest oceniany poza górny element powyższego dokumentu XML The Wanted, poprawny wynik jest produkowany:

2012 2011 2014 

I to jest XSLT 2.0 - na podstawie weryfikacji:

<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> 
Powiązane problemy