2012-09-20 31 views
8

Với mảnh này của XMLXSL nếu thử nghiệm bắt đầu-với

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

tôi nên cần với XSL để đầu ra chỉ năm của chuỗi không bắt đầu vớiinfo:eu-repo. Tôi đang cố gắng theo cách này, nhưng nó không hoạt động. Tôi sai với 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> 

Trả lời

16

Tôi đoán bạn không cần ' trong truy vấn start-with của bạn, và bạn có thể muốn để lặp qua ngày hơi khác nhau:

<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

tôi đã thử mà không có 'nhưng không hoạt động. kết quả tôi có 2012 info

+0

Tôi đã chỉnh sửa câu trả lời của mình. Có vẻ như bạn cũng có vấn đề lặp lại. – DRCB

+0

cảm ơn bạn, xấu hổ với tôi, tôi đặt thử nghiệm bên ngoài iteraion –

1

Bạn cũng có thể sử dụng một template-match để có được những gì bạn muốn, ví dụ:

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

tôi có XML đầu vào này:

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

và áp dụng XSLT này với nó:

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

và tôi nhận được kết quả này:

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

Trân trọng, Peter

1

Sử dụng (giả sử các đoạn XML cung cấp là các phần tử là con của nút hiện tại và chỉ có một phần tử có thuộc tính mong muốn):

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

XSLT - dựa xác minh:

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

Khi chuyển đổi này được áp dụng cho các tài liệu XML sau (đoạn cung cấp bọc trong một yếu tố hàng đầu duy nhất và không gian tên tuyên bố):

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

biểu thức XPath được đánh giá khỏi phần tử trên cùng và lại sult của đánh giá này được sao chép vào đầu ra:

2012 

II. Nhiều hơn một phần tử có thuộc tính mong muốn:

Trong trường hợp này Không thể tạo dữ liệu mong muốn bằng một biểu thức XPath 1.0 đơn lẻ.

chuyển đổi XSLT này:

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

khi áp dụng trên tài liệu XML này:

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

tạo ra truy nã, kết quả chính xác:

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

III. XPath 2.0 one-liner

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

Khi biểu thức này XPath 2.0 được đánh giá ngoài các yếu tố trên cùng của tài liệu XML mới nhất (gần nhất ở trên), những năm truy nã được sản xuất:

2012 2011 

Xác minh dựa trên XSLT 2.0:

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

Khi chuyển đổi này được áp dụng trên các tài liệu XML ngoái, biểu thức XPath được đánh giá và kết quả của đánh giá này được sao chép vào đầu ra:

2012 2011 

IV. Tổng Hầu hết và Khó trường hợp:

Bây giờ, chúng ta hãy có tài liệu XML này:

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

Chúng tôi vẫn muốn để có được một phần năm của tất cả các dc:date yếu tố có giá trị chuỗi không bắt đầu bằng 'thông tin: eu-repo '. Tuy nhiên, không có giải pháp nào trước đây hoạt động chính xác với phần tử dc:date cuối cùng ở trên.

Đáng chú ý, các dữ liệu truy nã vẫn có thể được sản xuất bởi một XPath đơn 2.0 biểu:

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

Khi biểu thức này được đánh giá ngoài các yếu tố trên cùng của tài liệu XML trên, truy nã, kết quả chính xác được sản xuất:

2012 2011 2014 

Và đây là XSLT 2.0 - có trụ sở xác minh:

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