2011-08-01 25 views
5

Tôi là một lập trình viên có kinh nghiệm, nhưng là người mới làm quen với XSLT và tôi thấy nó khá khó hiểu. Tôi xin lỗi nếu đây là một câu hỏi đã được hỏi trước đó, nhưng tôi rất thất vọng bởi XSLT rằng tôi thậm chí không chắc chắn những gì để tìm kiếm ...chọn một trong nhiều yếu tố khác nhau trong thuộc tính

Tôi có vấn đề là nếu một phần tử XML nào đó chỉ xuất hiện một lần, tôi muốn đầu ra nội dung của nó, nhưng nếu nó xuất hiện nhiều lần, tôi chỉ muốn nội dung của những người có thuộc tính nhất định.

Ví dụ, giả sử tôi có một tập tin XML (gọi nó là "nộp 1") có chứa

<food> 
    <snack>Chips</snack> 
    <snack type="nuts">Peanuts</snack> 
</food> 

và tập tin XML khác ("tập 2") có chứa

<food> 
    <snack>Cheese puffs</snack> 
</food> 

tôi cần XSLT chỉ xuất ra "Peanuts" (nhưng không phải "Chips") khi xử lý tệp 1, nhưng vẫn xuất ra "Cheese puffs" cho tệp 2 (nghĩa là tôi không thể chỉ chọn những phần tử có thuộc tính "type", Đó sẽ là quá dễ dàng).

Đây có lẽ là đơn giản, nhưng tôi bị mắc kẹt ...

+0

Câu hỏi hay, +1. Xem câu trả lời của tôi cho một giải pháp hoàn chỉnh, ngắn gọn và dễ dàng dựa trên các mẫu thiết kế XSLT cơ bản và mạnh mẽ nhất - sự ghi đè của quy tắc nhận dạng. Giải thích cũng được cung cấp. –

Trả lời

1

này chuyển đổi:

<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="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
    "*[snack/@type]/snack[not(@type)]"/> 
</xsl:stylesheet> 

tạo ra kết quả mong muốn trong cả hai trường hợp.

Giải thích:

  1. Nguyên tắc sắc/mẫu bản sao tất cả các nút "như nó vốn có".

  2. Mẫu thứ hai là trọng template sắc cho bất kỳ yếu tố snack mà không có một thuộc tính type đã anh chị em snack yếu tố mà có một thuộc tính type. Mẫu này có phần thân trống, có hiệu quả "xóa" phần tử được so khớp từ (được sao chép sang) đầu ra.

+0

Brilliant! Hoạt động tuyệt vời! Cảm ơn. Không bao giờ trong trí tưởng tượng điên rồ nhất của tôi, tôi đã nghĩ đến việc giải quyết vấn đề với 2 mẫu: một khuôn mẫu gần giống với những gì tôi muốn, và cái kia nghĩa đen không làm gì cả. Tại sao các thành ngữ XSLT phải như vậy là trực quan :-) – NumerousHats

0

nếu một phần tử XML nào đó chỉ xuất hiện một lần, tôi muốn đầu ra nội dung của nó, nhưng nếu nó xảy ra nhiều hơn một lần, tôi muốn chỉ là nội dung của những người có một thuộc tính nhất định.

Một bản dịch trực tiếp đó sẽ là

if (count(snack) = 1) then snack else snack[@type='nuts'] 

đó là XPath hợp lệ 2,0 cú pháp - nếu bạn cần phải làm điều đó trong 1,0 sau đó nó dịch khá trực tiếp (mặc dù một cách chi tiết) vào một xsl tương đương: chọn .

Nếu bạn muốn một cái gì đó thậm chí ngắn gọn hơn so với ở trên, bạn cũng có thể viết trong XPath 2,0

(snack[@type='nuts'], snack)[1] 

mà xây dựng một danh sách có chứa đầu tiên những món ăn nhẹ với type = 'hạt', sau đó tất cả các đồ ăn nhẹ, và sau đó chọn mục đầu tiên từ danh sách này.

Các vấn đề liên quan