2011-02-01 37 views
17

Tôi đang viết một phép chuyển đổi XSL. Tôi muốn viết một mẫu phù hợp với tất cả các phần tử con của tài liệu ngoại trừ một nút cụ thể. xml của tôi trông như thế này -Làm thế nào để viết một xpath để phù hợp với tất cả các yếu tố ngoại trừ một yếu tố cụ thể

<Document> 
    <NodeA></NodeA> 

    <NodeB></NodeB> 

    <ServiceNode></ServiceNode> 

    <NodeX></NodeX> 
</Document> 

Tôi muốn viết một mẫu phù hợp với tất cả các nút trừ ServiceNode ví dụ NodeA để NodeX. Làm thế nào để viết XPath này để có được -

<xsl:template match="ALL Nodex Except ServiceNode"> 
+0

Tốt câu hỏi, 1. Xem câu trả lời của tôi cho bốn giải pháp thay thế cho bốn ý nghĩa khác nhau có thể có của câu hỏi này. –

Trả lời

26

Tôi muốn viết mẫu khớp với tất cả các nút ngoại trừ ServiceNode tức là NodeA đến NodeX.

Nếu bởi "nút" bạn có nghĩa là phần tử, sau đó sử dụng:

<xsl:template match="*[not(self::ServiceNode)]"> 

Nếu bởi "nút" bạn có nghĩa là bất kỳ nút (kiểu phần tử, văn bản, nhận xét, xử lý-hướng dẫn) : sử dụng

<xsl:template match="node()[not(self::ServiceNode)]"> 

Nếu bạn muốn chỉ có trẻ em của Document là phù hợp sử dụng:

<xsl:template match="Document/node()[not(self::ServiceNode)]"> 

Nếu bạn muốn sử dụng chỉ có trẻ em trong những yếu tố hàng đầu để được xuất hiện:

<xsl:template match="/*/node()[not(self::ServiceNode)]"> 
2
<xsl:template match="Document/*[name() != 'ServiceNode']"> 

(hoặc local-name() nếu bạn phải đối phó với không gian tên)

+0

Tôi khuyên bạn nên thử nghiệm trong một bộ đánh giá trực tiếp như http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm nơi bạn có thể dán các biểu thức như // * [name()! = "Pet"] –

+0

Rất lỗi dễ bị ... –

0
/Document/*[not(name()='ServiceNode')] 
4

Bạn nên sử dụng tốt hơn biểu thức này:

*[not(self::ServiceNode)] 

Được kết hợp trong XSLT:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 

    <xsl:template match="/*"> 
     <xsl:apply-templates select="*[not(self::ServiceNode)]"/> 
    </xsl:template> 

    <xsl:template match="*"> 
     <xsl:value-of select="."/> 
     <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 

Với mẫu XML này:

<Document> 
    <NodeA>1</NodeA> 
    <NodeB>2</NodeB> 
    <ServiceNode>3</ServiceNode> 
    <NodeX>4</NodeX> 
</Document> 

Nó sẽ cho một kết quả chính xác:

1 
2 
4 
+4

Đúng. Điều này tốt hơn thử nghiệm trên name() hoặc local-name(). Trong XPath 2.0 phương án thay thế là (* ngoại trừ Mã dịch vụ) –

+0

Tôi đồng ý. Tốt hơn 'name()'. –

+0

@Alejandro, đừng quên để upvote, nếu bạn xem xét;) – Flack

1

Bạn có thể sử dụng hai mẫu:

<xsl:template match="Document/*"> 
    ...do something... 
</xsl:template> 


<xsl:template match="Document/ServiceNode" /> 

Mẫu sau sẽ được ưu tiên, do đó, mẫu đầu tiên sẽ khớp với mọi thứ ngoại trừ ServiceNode.

+0

Điều này có thể hữu ích trong một số trường hợp, bên cạnh đó nó không trả lời câu hỏi này đúng cách. –

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