2012-06-18 32 views
10

Tôi đang làm việc trên XSLT, nơi tôi cần triển khai một cái gì đó như sau. Mẫu XML nguồn của tôi trông giống như thế này.Triển khai Khái niệm giá trị khóa trong XSLT

<?xml version="1.0" encoding="ISO-8859-1"?> 
    <catalog> 
     <cd> 
      <title>A</title> 
      <title>B</title> 
      <title>C</title> 
     </cd> 
    </catalog> 

Hãy xem xét có một số danh sách cặp giá trị khóa ở đó.

Key   Value 
    A   Algebra 
    B   Biology 
    C   Chemistry 
    D   Data Analysis 
    ---   --- 

    ----  --- 

tôi cần phải viết một XSLT như vậy mà cho mỗi sự xuất hiện của khóa 'A', cần phải thay thế với giá trị thích hợp.

Tôi cũng cần đề cập đến danh sách các cặp khóa giá trị trong cùng một XSLT. Kết quả mẫu:

<Data> 
    <Subject>Algebra</Subject> 
    <Subject>Biology</Subject> 
    <Subject>Chemistry</Subject> 
</Data> 

Bất kỳ ai cũng có thể giúp tôi cách thực hiện.

Cảm ơn bạn.

Trả lời

16

I. Simple XSLT 1.0 Giải pháp

chuyển đổi này:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<my:codes> 
    <code key="A" value="Algebra"/> 
    <code key="B" value="Biology"/> 
    <code key="C" value="Chemistry"/> 
    <code key="D" value="Data Analysis"/> 
</my:codes> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
    "title/text()[. = document('')/*/my:codes/*/@key]"> 

    <xsl:value-of select= 
    "document('')/*/my:codes/*[@key=current()]/@value"/> 
</xsl:template> 
</xsl:stylesheet> 

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

<catalog> 
    <cd> 
     <title>A</title> 
     <title>B</title> 
     <title>C</title> 
    </cd> 
</catalog> 

tạo ra muốn, đúng kết quả:

<catalog> 
    <cd> 
     <title>Algebra</title> 
     <title>Biology</title> 
     <title>Chemistry</title> 
    </cd> 
</catalog> 

Giải thích:

Đây là cách tiêu chuẩn bao gồm nút inline XML như là một yếu tố toàn cầu (phần tử con của xsl:stylesheet) mà thuộc về một (không có sản phẩm nào) không gian tên, khác với không gian tên xsl.


II. hiệu quả hơn XSLT 1.0 giải pháp, sử dụng các phím:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:my="my:my"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <my:codes> 
     <code key="A" value="Algebra"/> 
     <code key="B" value="Biology"/> 
     <code key="C" value="Chemistry"/> 
     <code key="D" value="Data Analysis"/> 
    </my:codes> 

    <xsl:key name="kCodeByName" match="code" use="@key"/> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match= 
     "title/text()[. = document('')/*/my:codes/*/@key]"> 

     <xsl:variable name="vCur" select="."/> 

     <xsl:for-each select="document('')"> 
      <xsl:value-of select= 
      "key('kCodeByName', $vCur)/@value"/> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

khi chuyển đổi này được áp dụng trên cùng tài liệu XML (ở trên), cùng đúng, muốn kết quả được sản xuất:

<catalog> 
    <cd> 
     <title value="Algebra"/> 
     <title value="Biology"/> 
     <title value="Chemistry"/> 
    </cd> 
</catalog> 

Giải thích:

Truy cập dữ liệu qua chức năng key() thường là tuyến tính phụ - thường là O (1) và cực kỳ fas ter hơn tìm kiếm tuyến tính (điều quan trọng nếu số lượng nút được tìm kiếm lớn).

Truy cập nút của một tài liệu qua chỉ mục (xsl:key) trong khi xử lý một nút của tài liệu khác là có thể nếu tài liệu chứa nút cần tra cứu là tài liệu hiện tại. Để truy cập các nút từ tài liệu khác, gốc của nó (hoặc nút quan tâm cần phải được lưu và tham chiếu một biến.)


III. giải pháp XSLT 2.0:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="vCodes"> 
    <codes> 
    <code key="A" value="Algebra"/> 
    <code key="B" value="Biology"/> 
    <code key="C" value="Chemistry"/> 
    <code key="D" value="Data Analysis"/> 
    </codes> 
</xsl:variable> 

<xsl:key name="kCodeByName" match="code" use="string(@key)"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
    "title/text()[key('kCodeByName', ., $vCodes)]"> 

    <xsl:sequence select= 
    "key('kCodeByName', ., $vCodes)/@value"/> 
</xsl:template> 
</xsl:stylesheet> 

khi chuyển đổi này được áp dụng trên cùng tài liệu XML (ở trên), cùng đúng, kết quả muốn được sản xuất:

<catalog> 
    <cd> 
     <title value="Algebra"/> 
     <title value="Biology"/> 
     <title value="Chemistry"/> 
    </cd> 
</catalog> 

Giải thích:

Hầu như giống như giải pháp XSLT 1.0 hiệu quả, nhưng:

  1. Trong XSLT 2.0, mẫu đối sánh mẫu có thể chứa tham chiếu biến.

  2. Trong XSLT 2.0 không cần thủ thuật nhào lộn thao tác tài liệu hiện tại và tài liệu được lập chỉ mục - đối số thứ 3 của hàm key() là chỉ định cây có chỉ mục để sử dụng.

+0

Cảm ơn bạn đã trả lời. – Patan

+0

@ User222: Bạn được chào đón. –

+0

@Dimitre Chúng ta có thể gọi mẫu trong giải pháp III. XSLT 2.0 trong một mẫu khác. Nếu có, bạn có thể cho tôi biết bằng cách nào không? –

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