2010-06-01 27 views
5

Tôi mới dùng XPath và từ những gì tôi đã đọc trong một số hướng dẫn về trục, tôi vẫn còn tự hỏi làm cách nào để triển khai chúng. Chúng không hoạt động như tôi mong đợi. Tôi đặc biệt quan tâm đến việc sử dụng tổ tiên và trục hậu duệ.Tổ tiên XPath và hậu duệ trong bản sao XSL của

tôi có cấu trúc XML sau:

<file> 
    <criteria> 
     <root>ROOT</root> 
     <criterion>AAA</criterion> 
     <criterion>BBB</criterion> 
     <criterion>CCC</criterion> 
    </criteria> 
    <format> 
     <sort>BBB</sort> 
    </format> 
</file> 

Và tôi có XSL sau:

<xsl:template match="/"> 
    <xsl:copy-of select="ancestor::criterion/> 
</xsl:template> 

trong đó sản xuất không có gì!

tôi mong đợi nó để sản xuất:

<file> 
    <criteria> 
    </criteria> 
</file> 

Ai đó có thể giải thích tổ tiên và trục hậu duệ với tôi theo một cách hữu ích hơn so với hướng dẫn Tôi đã đọc trước đó?

Cảm ơn!

+0

Câu hỏi hay (+1). Xem câu trả lời của tôi cho một lời giải thích và một giải pháp hoàn chỉnh. –

Trả lời

5

Và tôi có XSL sau:

<xsl:template match="/"> 
    <xsl:copy-of select="ancestor::criterion/> 
</xsl:template> 

trong đó sản xuất không có gì!

Như vậy!

ancestor::criterion 

là biểu thức tương đối, có nghĩa là nó được đánh giá khỏi nút hiện tại (khớp với mẫu). Nhưng nút hiện tại là nút tài liệu /.

Vì vậy, phía trên là tương đương với:

/ancestor::criterion 

Tuy nhiên, theo định nghĩa tài liệu nút / không có cha mẹ (và đó có nghĩa là không có tổ tiên), vì vậy biểu thức XPath này không chọn bất kỳ nút.

tôi mong đợi nó để sản xuất:

<file> 
    <criteria> 
    </criteria> 
</file> 

Những gì bạn có thể muốn là:

//criterion/ancestor::* 

hoặc

//*[descendant::criterion] 

Hai biểu thức XPath cuối cùng là tương đương và lựa chọn tất cả các phần tử có con cháu criterion.

Cuối cùng, để tạo đầu ra bạn muốn, đây là một trong những giải pháp khả thi:

<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="root | criterion | format"/> 
</xsl:stylesheet> 

Khi chuyển đổi này được áp dụng trên các tài liệu XML được cung cấp, sản lượng truy nã được sản xuất:

<file> 
<criteria> 
</criteria> 
</file> 
+0

Cảm ơn bạn đã phản hồi. // tiêu chí/tổ tiên :: * và // * [hậu duệ :: tiêu chí] cho tôi kết quả lạ và trong khi giải pháp được mã hóa đầy đủ mà bạn cung cấp không hoạt động và tạo ra kết quả mong đợi, tôi vẫn cần một giải pháp mã hóa ít hơn (ở trên giải pháp đòi hỏi kiến ​​thức về gốc và định dạng .. nhưng có thể có những người khác mà tôi không biết về ..) Ngoài ra, cảm ơn lời giải thích về con cháu và trục tổ tiên :) – developer

+0

@iHeartGreek: Tại sao bạn mong đợi một biểu thức XPath chọn các nút cụ thể để chọn các nút khác? Trong trường hợp bạn có vấn đề khác, chỉ cần hỏi một câu hỏi khác. Bạn chưa đặt câu hỏi chưa được trả lời. :) –

1

ancestor là để chọn các nút cao hơn (gần gốc hơn) trong tài liệu XML. descendant là để chọn các nút thấp hơn (trẻ em) trong tài liệu XML.

Trong ví dụ của bạn, ancestor::criterion chọn gì bởi vì nút hiện tại là / (có nghĩa là thư mục gốc của tài liệu - <file> trong trường hợp này), như được chỉ ra bởi match="/". Nút gốc không có tổ tiên nên trục ancestor không làm gì cả.

Để có được tất cả các yếu tố <criterion>, bạn nên sử dụng descendant trục:

<xsl:template match="/"> 
    <xsl:copy-of select="descendant::criterion"/> 
</xsl:template> 

Hoặc shortcut của nó //:

<xsl:template match="/"> 
    <xsl:copy-of select="//criterion"/> 
</xsl:template> 

Điều đó sẽ trở lại như sau:

<criterion>AAA</criterion> 

Sử dụng một vòng lặp hoặc một mẫu khác, bạn có thể nhận được cả ba họ:

<xsl:template match="/"> 
    <file> 
    <xsl:apply-templates select="//criterion"/> 
    </file> 
</xsl:template> 
<xsl:template match="criterion"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

này sẽ tạo ra những điều sau đây:

<file> 
    <criterion>AAA</criterion> 
    <criterion>BBB</criterion> 
    <criterion>CCC</criterion> 
</file> 

Nếu bạn muốn để có được những yếu tố <file> cũng vậy, nó phức tạp hơn một chút. XPath chỉ định các nút và các bản sao đơn giản sẽ không sao chép các phần tử chứa các phần tử bạn chọn. Tôi có thể làm rõ thêm điểm này nếu bạn vẫn còn bối rối.

+0

Bạn nói rằng: ' ' sẽ trở lại như sau: ' AAA' Đây không phải như vậy. Kết quả sẽ là: ' AAA BBB CCC' –

+0

Chỉ cần một điểm, nhưng 'hậu duệ :: criterion' là không tương đương với '// criterion'; sau này sẽ tìm thấy tất cả các nút tiêu chí trong toàn bộ tài liệu. Phím tắt chính xác là '.// tiêu chí'. – Flynn1179

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