2011-12-07 38 views
10

tôi đã biến XSLT sau:Kiểm tra nếu nút có thuộc tính tương đương với giá trị tồn tại

<xsl:variable name="superid" select="/contentdata/id"/> 

Hơn nữa, tôi có một nút với subnodes:

<nodes> 
    <node name="foo" id="bar" /> 
    <node name="john" id="doe" /> 
    <node name="jane" id="tarzan" /> 
</nodes> 

Bây giờ, tôi muốn kiểm tra xem một nút có thuộc tính id bằng superid tồn tại.

Tôi đã thử những điều sau đây (mà rõ ràng là không hoạt động):

<xsl:if test="/nodes/node[@id = $superid]">Yes, Sir!</xsl:if> 
+0

Giá trị biến $ superid là gì? – Vitaliy

+0

Thông báo lỗi bạn đang nhận được là gì? Tôi tin rằng nó có thể là phiên bản .NET và bạn đang sử dụng xslt v1 hoặc v2. Vui lòng cung cấp cho chúng tôi thông tin này. Tạo một fiddle trong khi bạn đang ở đó :) –

Trả lời

15

Sử dụng:

boolean(/nodes/node/@id = $superid) 

Đây là một chuyển đổi hoàn toàn, cho thấy điều này trong hành động:

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

<xsl:variable name="vDoe" select="'doe'"/> 
<xsl:variable name="vXyz" select="'xyz'"/> 

<xsl:template match="/"> 
    id attribute with value "doe' exists: <xsl:text/> 
    <xsl:value-of select="boolean(/nodes/node/@id = $vDoe)"/> 
========== 
    id attribute with value "xyz' exists: <xsl:text/> 
    <xsl:value-of select="boolean(/nodes/node/@id = $vXyz)"/> 
</xsl:template> 
</xsl:stylesheet> 

khi chuyển đổi này được áp dụng trên các tài liệu XML cung cấp:

<nodes> 
    <node name="foo" id="bar" /> 
    <node name="john" id="doe" /> 
    <node name="jane" id="tarzan" /> 
</nodes> 

sự muốn, kết quả chính xác được sản xuất:

 id attribute with value "doe' exists: true 
========== 
    id attribute with value "xyz' exists: false 
4

Những gì bạn có vẻ làm việc cho tôi (Net 3.5) - theo here.

tôi đã cố gắng để tái tạo của bạn xslt:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       version="1.0" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       > 
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" /> 

    <xsl:template match="/xml"> 
     <xml> 
      <xsl:apply-templates select="contentdata/id" /> 
     </xml> 
    </xsl:template> 

    <xsl:template match="id"> 
     <Result> 
     <xsl:variable name="superid" select="."/> 
     <SearchFor> 
      <xsl:value-of select="$superid"/> 
     </SearchFor> 
     <IsPresent> 
      <xsl:if test="/xml/nodes/node[@id = $superid]">Node is present</xsl:if> 
     </IsPresent> 
    </Result> 
    </xsl:template> 

</xsl:stylesheet> 

Với xml:

<xml> 
    <contentdata> 
     <id>doe</id> 
     <id>unobtanium</id> 
    </contentdata> 
    <nodes> 
     <node name='foo' id='bar' /> 
     <node name='john' id='doe' /> 
     <node name='jane' id='tarzan' /> 
    </nodes> 
</xml> 

Output:

<xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Result> 
     <SearchFor>doe</SearchFor> 
     <IsPresent>Node is present</IsPresent> 
    </Result> 
    <Result> 
     <SearchFor>unobtanium</SearchFor> 
     <IsPresent /> 
    </Result> 
</xml> 
3

Nếu bạn đang sử dụng biểu thức xpath /nút/node [@id = $ superid] "> thì đây sẽ là looki ng cho nút gốc của các nút trong tài liệu XML của bạn. Tuy nhiên, trong câu hỏi của bạn, bạn dường như ngụ ý các nút chỉ là một nút trong tài liệu của bạn, không nhất thiết phải là phần tử gốc. Hãy thử điều này thay vì

<xsl:if test="//nodes/node[@id = $superid]">Yes, Sir!</xsl:if> 

Dấu gạch chéo kép chọn các nút trong tài liệu ở bất kỳ đâu trong phân cấp, không chỉ nút cấp cao nhất.

1

này nên được làm việc như bạn mong đợi. Một trong các biểu thức của bạn (hoặc trong biến số select hoặc thuộc tính test) không được chọn những gì bạn nghĩ. (Bạn chưa cung cấp đầy đủ thông tin đầu vào của mình, vì vậy thật khó để giúp bạn ở đó.)

Lưu ý một vài điều về xsl:if:

  • Đầu tiên, xem this part of the XSLT spec (nhấn mạnh của riêng tôi):

    Các xsl: nếu phần tử có một thuộc tính kiểm tra, trong đó xác định một biểu thức . Nội dung là một mẫu. Biểu thức được đánh giá và đối tượng kết quả là được chuyển thành boolean như thể gọi bằng hàm boolean. Nếu kết quả là đúng, thì mẫu nội dung là được khởi tạo; nếu không, không có gì được tạo ra.

  • Vậy làm cách nào để gọi hàm boolean hoạt động trên đầu vào của bạn? Xem this part of the XPath spec (một lần nữa, tôi nhấn mạnh):

    Chức năng boolean chuyển đổi đối số của nó để một boolean như sau:

    • một số là đúng nếu và chỉ nếu nó không phải là tích cực hay tiêu cực không hay NaN

    • một node-set là đúng nếu và chỉ nếu nó không bị để trống

    • một chuỗi là đúng nếu và chỉ nếu chiều dài của nó không phải là zero

    • một đối tượng của một loại khác với bốn loại cơ bản được chuyển thành một boolean trong một cách mà phụ thuộc vào loại

vì vậy, nếu thực sự /contentdata/id chọn một id/nodes/node[@id = $superid] trả về một nút-set không trống, sau đó cơ thể của xsl:if nên thực thi.

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