2009-08-14 33 views
5

Tôi đang kéo phần còn lại của tóc ra để tìm kiếm bên ngoài đơn giản bằng cách sử dụng Saxon 9.1.0.7.XSLT 2.0 tra cứu bên ngoài bằng cách sử dụng phím() và tài liệu()

Tôi có một file nguồn đơn giản dummy.xml:

<something> 
    <monkey> 
     <genrecode>AAA</genrecode> 
    </monkey> 
    <monkey> 
     <genrecode>BBB</genrecode> 
    </monkey> 
    <monkey> 
     <genrecode>ZZZ</genrecode> 
    </monkey> 
    <monkey> 
     <genrecode>ZER</genrecode> 
    </monkey> 
</something> 

Sau đó, các tập tin tra cứu là GenreSet_124.xml:

<GetGenreMappingObjectsResponse> 
    <tuple> 
     <old> 
     <GenreMapping DepartmentCode="AAA" 
         DepartmentName="AND - NEWS AND CURRENT AFFAIRS" 
         Genre="10 - NEWS"/> 
     </old> 
    </tuple> 
    <tuple> 
     <old> 
     <GenreMapping DepartmentCode="BBB" 
         DepartmentName="AND - NEWS AND CURRENT AFFAIRS" 
         Genre="11 - NEWS"/> 
     </old> 
    </tuple> 

    ... lots more 
</GetGenreMappingObjectsResponse> 

gì tôi m cố gắng để đạt được chỉ đơn giản là để có được giữ của "Thể loại "giá trị dựa trên giá trị" DepartmentCode ".

Vì vậy, XSL của tôi trông giống như:

... 
<!-- Set up the genre lookup key --> 
<xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/> 


<xsl:variable name="lookupDoc" select="document('GenreSet_124.xml')"/> 

<xsl:template match="/something"> 
<stuff> 
    <xsl:for-each select="monkey"> 
     <Genre> 

     <xsl:apply-templates select="$lookupDoc"> 
     <xsl:with-param name="curr-label" select="genrecode"/> 
     </xsl:apply-templates> 

     </Genre> 
    </xsl:for-each> 
</stuff> 
</xsl:template> 

<xsl:template match="GetGenreMappingObjectsResponse"> 
    <xsl:param name="curr-genrecode"/> 

    <xsl:value-of select="key('genre-lookup', $curr-genrecode)/@Genre"/> 

</xsl:template> 

...


Vấn đề mà tôi có là tôi nhận được gì trở lại. Tôi hiện chỉ nhận được

<?xml version="1.0" encoding="UTF-8"?> 
<stuff> 
    <Genre/> 
    <Genre/> 
    <Genre/> 
    <Genre/> 
</stuff> 

tôi đã chuyển tất cả dữ liệu tra cứu để có các thuộc tính của GenreMapping, trước đây là phần tử con của GenreMapping bất cứ khi nào tôi bước vào template match = "GetGenreMappingObjectsResponse" nó sẽ chỉ in ra tất cả các văn bản từ mọi GenreMapping (DepartmentCode, DepartmentName, Thể loại)!

Tôi không thể cho cuộc sống của tôi tìm ra những gì tôi đang làm sai. Bất kỳ helpo/góp ý sẽ được đánh giá rất nhiều.

xin vui lòng tìm việc niêm yết XSLT thực tế hiện nay:.

<?xml version="1.0"?> 
<xsl:stylesheet version="2.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

<!-- Define the global parameters --> 
<xsl:param name="TransformationID"/> 
<xsl:param name="TransformationType"/> 

<!-- Specify that XML is the desired output type --> 
<xsl:output method="xml" encoding="UTF-8" indent="yes"/> 

<!-- Set up the genre matching capability --> 
<xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/> 

<xsl:variable name="documentPath"><xsl:value-of select="concat('GenreSet_',$TransformationID,'.xml')"/></xsl:variable> 
<xsl:variable name="lookupDoc" select="document($documentPath)"/> 

<!-- Start the first match on the Root level --> 
<xsl:template match="/something"> 
<stuff> 
    <xsl:for-each select="monkey"> 
     <Genre> 
     <xsl:apply-templates select="$lookupDoc/*"> 
     <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
     </xsl:apply-templates> 
     </Genre> 
    </xsl:for-each> 
</stuff> 
</xsl:template > 

<xsl:template match="GetGenreMappingObjectsResponse"> 
    <xsl:param name="curr-genrecode"/> 
    <xsl:value-of select="key('genre-lookup', $curr-genrecode, $lookupDoc)/@Genre"/> 
</xsl:template> 
</xsl:stylesheet> 

Các TransformationID là alway 124 (do đó các tập tin tra cứu chính xác được mở Các Loại chỉ là một tên mà tôi hiện không sử dụng nhưng có ý định

.
+0

Trình biên dịch XSLT nào bạn đang sử dụng? – Welbog

+0

Saxon-B 9.1.0.7 –

+0

Số liệu. Tôi không quen với cái đó. Có lẽ sau này Tomalak sẽ đến và giúp bạn. Phương pháp keyless có hoạt động không? – Welbog

Trả lời

7

trong XSLT 2.0 có hai cách bạn có thể làm những gì bạn muốn:

Một là phiên bản ba tham số của key chức năng tham số thứ ba cho phép bạn chỉ định các nút gốc bạn muốn chìa khóa để làm việc trên (. theo mặc định luôn thư mục gốc của tài liệu chính):

<xsl:value-of select="key('genre-lookup', $curr-genrecode,$lookupDoc)/@Genre"/> 

Một cách khác là sử dụng các chức năng key dưới $lookupDoc nút:

<xsl:value-of select="$lookupDoc/key('genre-lookup', $curr-genrecode)/@Genre"/> 

Cả hai phương pháp được diễn tả trong các XSLT 2.0 specification on keys, và sẽ không làm việc trong XSLT 1.0.

Vì mục đích hoàn chỉnh, bạn phải viết lại điều này để không sử dụng khóa nếu bạn bị giới hạn ở XSLT 1.0.

<xsl:value-of select="$lookupDoc//GenreMapping[@DepartmentCode = $curr-genrecode]/@Genre"/> 

Aha! Sự cố là select="$lookupDoc" trong cuộc gọi apply-templates của bạn đang gọi mẫu mặc định thay vì mẫu bạn mong đợi, vì vậy thông số sẽ bị mất.

Thay đổi nó như thế này:

<xsl:apply-templates select="$lookupDoc/*"> 
    <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
</xsl:apply-templates> 

Đó sẽ gọi mẫu của bạn đúng cách và phím nên làm việc.

Vì vậy, các tấm XSLT thức nên tìm một cái gì đó như thế này:

<xsl:variable name="lookupDoc" select="document('XMLFile2.xml')"/> 
    <xsl:key name="genre-lookup" match="GenreMapping" use="@DepartmentCode"/> 
    <xsl:template match="/something"> 
    <stuff> 
     <xsl:for-each select="monkey"> 
     <Genre> 
      <xsl:apply-templates select="$lookupDoc/*"> 
      <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
      </xsl:apply-templates> 
     </Genre> 
     </xsl:for-each> 
    </stuff> 
    </xsl:template> 
    <xsl:template match="GetGenreMappingObjectsResponse"> 
    <xsl:param name="curr-genrecode"/> 
    <xsl:value-of select="key('genre-lookup',$curr-genrecode,$lookupDoc)/@Genre"/> 
    </xsl:template> 

(Source of information)

+0

HI ở đó, Cảm ơn bạn đã phản hồi. Tôi đã thử (và bây giờ đã thử lại) cả hai (từ trong mẫu chính, tôi không gọi áp dụng mẫu bằng cách sử dụng biểu mẫu này) và cả hai đều không trả về gì cả. Tôi vẫn nhận được các yếu tố trống rỗng ?! Phải có điều gì đó mà tôi đang làm sai trong quá trình thiết lập khóa? liên quan –

+0

Đây có thể là vấn đề cụ thể với trình biên dịch XSLT của bạn, nhưng sử dụng '$ lookupDoc/*' sẽ bao gồm các cơ sở của bạn. – Welbog

+0

Xin chào một lần nữa, Sử dụng mã đã cập nhật Tôi không còn nhận được các phần tử trống nữa Tôi nhận được đầy đủ khoảng trắng (giá trị 24 dòng). Tôi thực sự bối rối. –

0

OK, vì vậy đây là một chút tinh thần và tôi không yêu cầu phải hiểu nó nhưng nó hoạt động (có vẻ như một nghề nghiệp trong phần mềm).

Vấn đề tôi gặp phải là khi tôi gọi các mẫu áp dụng và chuyển vào tài liệu bên ngoài dưới dạng biến, nó không bao giờ khớp với bất kỳ mẫu nào thậm chí là các mẫu được gọi là "Genremapping".

Vì vậy, tôi đã sử dụng một ký tự đại diện để bắt nó, cũng như khi gọi các mẫu áp dụng, tôi thu hẹp bộ nút là con tôi quan tâm. xem "GenreMapping" nhưng nó không bao giờ đi vào bất kỳ mẫu nào mà tôi đã gọi là "GenreMapping", thay vào đó chỉ chọn mẫu "*".

Điều này có nghĩa là đối sánh mẫu mới của tôi được gọi cho mỗi nút GenreMapping duy nhất, do đó có thể có một chút không hiệu quả. Những gì tôi nhận ra sau đó là tất cả những gì tôi cần làm là in ra nếu một vị từ phù hợp.

Vì vậy, nó trông như thế này bây giờ (không sử dụng chìa khóa nào):

... 
<xsl:template match="/something"> 
<stuff> 
    <xsl:for-each select="monkey"> 
     <Genre> 
     <key_value><xsl:value-of select="genrecode"/></key_value> 
     <xsl:variable name="key_val"><xsl:value-of select="genrecode"/></xsl:variable> 
     <code> 
     <xsl:apply-templates select="$lookupDoc/*/*/*/*"> 
     <xsl:with-param name="curr-genrecode" select="string(genrecode)"/> 
     </xsl:apply-templates> 

     </code> 
     </Genre> 
    </xsl:for-each> 
</stuff> 
</xsl:template > 


<xsl:template match="*"> 
    <xsl:param name="curr-genrecode"/> 
    <xsl:value-of select=".[@DepartmentCode = $curr-genrecode]/@Genre"/> 
</xsl:template> 
... 

Tất cả những điều đầu ra: Lưu ý, các key_value cuối cùng một cách chính xác không có một mục mã như không có trận đấu trong tra cứu tài liệu.

<?xml version="1.0" encoding="UTF-8"?> 
<stuff xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <Genre> 
     <key_value>AAA</key_value> 
     <code>10 - NEWS</code> 
    </Genre> 
    <Genre> 
     <key_value>AAA</key_value> 
     <code>10 - NEWS</code> 
    </Genre> 
    <Genre> 
     <key_value>BBB</key_value> 
     <code>11 - NEWS</code> 
    </Genre> 
    <Genre> 
     <key_value>SVVS</key_value> 
     <code/> 
    </Genre> 
</stuff> 

Trả lời trên mã bưu điện. Cảm ơn sự giúp đỡ Welbog.

+0

Tôi rất vui vì bạn đã tìm được giải pháp làm việc, mặc dù nó là một giải pháp kỳ quặc. – Welbog

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