2011-10-29 40 views
7

Tôi có một vấn đề nhỏ, có cách nào để bao gồm động một xsl khác không? Ví dụ:Tự động bao gồm các tệp XSL khác trong XSLT

<xsl:variable name="PathToWeb" select="'wewe'"/> 
<xsl:include href="http://{$PathToWeb}/html/xsl/head.xsl" /> 
<xsl:include href="http://{$PathToWeb}/html/xsl/navigation.xsl" /> 
<xsl:include href="http://{$PathToWeb}/html/xsl/promo.xsl" /> 
<xsl:include href="http://{$PathToWeb}/html/xsl/3columns.xsl" /> 

<xsl:include href="http://{$PathToWeb}/html/xsl/footer.xsl" /> 
+0

sử dụng bvb1909

Trả lời

2

Bạn không thể thực hiện việc này. Lý do rất đơn giản:

XSL trước tiên sẽ mở rộng xsl: include trong khi biên dịch, trước khi thực hiện bất kỳ điều gì khác. Tại thời điểm đó, "biến" của bạn không biết và không thể được biết và bạn không thể thay đổi biến đổi được biên dịch khi nó biên dịch. Ngoài ra, href là một Uniform Resource Locator không phải là một biểu thức XPath, do đó bạn không thể chỉ mở rộng một biến trong đó.

+0

ok, nhưng đó là ngu ngốc ... trong php một bao gồm đơn giản() giải quyết vấn đề này ... và tôi thực sự cần điều này, tại sao được phát triển theo cách này? – Master345

+0

Tôi không biết tại sao nhưng xslt! = Php Tôi sợ :) – FailedDev

+1

@Row Minds Đây là bản dịch chính xác câu trả lời của bạn bắt đầu bằng "ok, nhưng điều đó thật ngu ngốc". Đây là nó: "Tôi tin rằng nó là ngu ngốc rằng một quả chuối không phải là trong miệng của tôi chính xác và mỗi khi tôi muốn ăn một quả chuối. Khi tôi ăn PHP, nó là ngon". Thực tế là công nghệ khỉ-hoot (thay thế bất kỳ tên nào ở đây, có lẽ PHP) thực hiện một sự bao gồm trong thời trang bạn mong muốn không có cách nào làm cho nó sai công nghệ khác nhau-khỉ-hoot (thay thế bất kỳ tên ở đây, có lẽ xsl) thực hiện một bao gồm một cách khác nhau . – DwB

5

Tôi gặp sự cố nhỏ, có cách nào để bao gồm động khác xsl? Ví dụ:

<xsl:variable name="PathToWeb" select="'wewe'"/> 
<xsl:include href="http://{$PathToWeb}/html/xsl/head.xsl" /> 
<xsl:include href="http://{$PathToWeb}/html/xsl/navigation.xsl" /> 
<xsl:include href="http://{$PathToWeb}/html/xsl/promo.xsl" /> 
<xsl:include href="http://{$PathToWeb}/html/xsl/3columns.xsl" /> 

<xsl:include href="http://{$PathToWeb}/html/xsl/footer.xsl" /> 

Đó là bất hợp pháp để có một tham chiếu biến trong href thuộc tính của <xsl:include>. Theo thông số W3C XSLT 1.0 và XSLT 2.0, giá trị của thuộc tính này phải là tham chiếu URI. Tuy nhiên, nếu giá trị của biến số $PathToWeb được biết trước khi bắt đầu chuyển đổi, nó có thể được sử dụng theo một số cách để tạo ra biểu diễn kiểu dáng động trong đó các câu lệnh <xsl:include> ở trên chứa các URI mong muốn (sau khi thay thế) tham chiếu đến $PathToWeb với giá trị yêu cầu:

  1. Tạo một kiểu mới từ dòng điện một, sử dụng XSLT

  2. Load. biểu định kiểu làm đối tượng XmlDocument. Sau đó, tìm các phần tử <xsl:include> tương ứng và đặt thuộc tính href của chúng thành các giá trị mong muốn. Cuối cùng, gọi phép chuyển đổi bằng cách sử dụng XmlDocument đã sửa đổi đại diện cho biểu định kiểu.

Phương pháp 2. đã được sử dụng cho 11 năm trong XPath Visualizer để tự động thiết lập các giá trị chính xác của một thuộc tính select sử dụng để chọn tất cả các nút mà một biểu thức XPath sử dụng vào lựa chọn và để tạo ra một tài liệu HTML đại diện cho tài liệu XML với tất cả các nút được chọn và hiển thị được đánh dấu.

+1

Tôi xác định theo kinh nghiệm với XMLSpy rằng ' 'không cho phép biểu thức XPath làm giá trị của thuộc tính' href' của nó, trong khi '' thực hiện. Tôi không thể tìm thấy bất cứ điều gì trong spec để hỗ trợ này, mặc dù. Có thực sự là một sự khác biệt giữa hai, hoặc nó là một lỗi/một phần mở rộng độc quyền? (Tôi thậm chí không thực sự sử dụng một biến, chỉ là bất kỳ biểu thức nào như {'test'}.) – Dabbler

+1

Nó không phải là một lỗi. AVT được phép cho thuộc tính 'href' của' 'với mục đích cho phép tạo nhiều tài liệu kết quả. Có sự khác biệt lớn giữa '' và ''. Trước đây chỉ có thể được xử lý tại thời gian biên dịch, sau đó được xử lý tại thời gian chạy. –

+3

Tôi không biết nhiều ngôn ngữ lập trình với các cấu trúc sửa đổi chương trình trong khi thực thi, vì vậy sẽ khá ngạc nhiên nếu xsl: bao gồm động được cho phép. Đối với spec, quy tắc cho xsl: include là '' trong khi đó đối với xsl: result-document là '

5

Tôi đã giải quyết vấn đề này theo cách khác, có thể hữu ích cho người làm việc với Java và XSLT (giải pháp này dành riêng cho những người đang sử dụng gói javax.xml.transform).

XSLT nhà máy biến áp cho phép thiết lập trình phân giải URI tùy chỉnh. Giả sử nếu XSLT của bạn trông như

<?xml version="1.0" encoding="utf-8"?> 
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" version="4.0" encoding="UTF-8"/> 
    <xsl:include href="import://stackoverflow.com/xsl"/> 
    ... 

Phương pháp URI phân giải của resolve sẽ nhận được import://stackoverflow.com/xsl như một tham số href. import:// có thể phục vụ như là một lược đồ định danh "đặc biệt" cho các tùy chỉnh bao gồm, vì vậy bạn có thể phát hiện nó và tạo/trả về javax.xml.transform.Source trỏ đến tệp cần thiết.Ví dụ:

TransformerFactory tf = TransformerFactory.newInstance(); 
URIResolver delegate = tf.getURIResolver(); 
tf.setURIResolver(new CustomURIResolver(delegate)); 

Sau đó, bên trong CustomURIResolver:

public Source resolve(String href, String base) 
    throws TransformerException { 
    Source result = null; 
    URI uri = null; 

    try { 
     uri = new URI(href); 
    } 
    catch(Exception e) { 
     throw new TransformerException(e); 
    } 

    // The XSLT file has a URI path that allows for a file to be included 
    // dynamically. 
    if("import".equalsIgnoreCase(uri.getScheme()) && 
     "stackoverflow.com".equalsIgnoreCase(uri.getAuthority())) { 
     result = openTemplate(); 
    } 
    else { 
     result = getDelegate().resolve(href, base); 
    } 

    return result; 
    } 

Thêm một phương pháp openTemplate() bao gồm logic để tự động xác định các tập tin XSL để mở.

0

Trong PHP, như dưới chế độ khác, nó là một quá trình gồm nhiều bước để sử dụng một XSL stylesheet:

1) Tạo một SimpleXML hoặc đối tượng DOMDocument từ một file XSL.

2) Tạo đối tượng XSLTProcessor.

3) Nhập đối tượng tài liệu XSL vào đối tượng bộ xử lý.

4) Chạy biến đổi trên tệp dữ liệu XML.

Sau 1), XSL có thể được thao tác trước khi được biên dịch như một phần của bước 3). Ở đây, các phần tử xsl: include có thể được chèn tự động khỏi phần tử gốc theo yêu cầu.

Do đó, để tự động chèn xsl: bao gồm:

1.1) Sử dụng XPath | getElementById | getElementsByTagName để kiểm tra dữ liệu XML cho sự tồn tại của các yếu tố mà bạn có thể yêu cầu thêm stylesheets.

1.2) Tự động tạo các phần tử xsl: include ra khỏi phần tử gốc của đối tượng XML của XSL.

Vậy đó. Ở bước 3), đối tượng XSL XML đã sửa đổi sẽ được biên dịch như thể nó được xây dựng theo cách đó từ đầu. Tất nhiên, tại 1.2), bất kỳ nút nào (không chỉ xsl: include hoặc xsl: import) từ các đối tượng tài liệu XSL khác có thể được thêm vào bất kỳ nút nào trong đối tượng tài liệu XSL cơ sở, cho phép kiểm soát tốt hơn nhiều. Tuy nhiên, việc xây dựng mẫu xsl: template thích hợp của tất cả các bảng định kiểu XSL sẽ làm cho nó đơn giản hơn nhiều khi chỉ chèn các phần tử xsl: include.

0

2 xu của tôi trị giá trên một sự thay thế đơn giản (nhưng hiệu quả) (chỉ psuedocode cung cấp để minh hoạ tiến hành thận trọng :)

Outline của phương pháp này:. Một giải pháp thay thế có thể bao gồm một kịch bản wrapper đơn giản (ví dụ shell, bash script hoặc khác) để gọi xsl chính của bạn, sử dụng các chế độ xslt tên, tệp xslt chính, một tệp xslt đơn giản (trống) được chỉ định.

Trong xsl chính, bao gồm tệp xsl tĩnh, sẽ gọi/tải tất cả xslt được bao gồm động. Sau đó, xsl chính sẽ hoạt động ở 2 chế độ: chế độ bình thường (chế độ không xác định), nơi nó sẽ tải các tệp xsl mở rộng trong chính nó, và trong các xls tĩnh và xử lý bất kỳ tệp đầu vào nào hoặc làm những gì tốt làm. Chế độ thứ hai, chế độ tiền xử lý, sẽ được dùng để tải các cá thể/tệp xsl được chỉ định dyanimically. Chế độ này sẽ được gọi là một giai đoạn tiền xử lý cho quá trình xử lý chính. Dòng quy trình cho xslt chính sẽ gọi nó bằng chế độ tiền xử lý được chỉ định, và sau đó gọi lại nó với chế độ xử lý thông thường được chỉ ra.

Gợi ý triển khai: Đối với mỗi xlator xác định một tệp xslt mở rộng, ext_xsl_container, có mục đích là bao gồm bất kỳ xslt mở rộng nào. ví dụ:

<xsl:stylesheet > 
    <!-- main xslt --> 
     <xsl:import href="../xsl/ext_xsl_container.xsl/> 
     <!--param: list of dynamically specified extension xsl --> 
     <xsl:param name="extXslUrlList"/> 
     <!--param:preprocessor mode flag, with default set to false --> 
     <xsl:param name="preProcModeLoadXslF" select="false()" type="xs:boolean" 
<!-- param: path to the staticall included ext_xsl_container: with default value set --> 
    <xsl:param name="extXslContainerUrl" select="'../xsl/ext_xsl_container.xsl'"/> 

     <xsl:if test=" ($preProcModeLoadXslF=true())" > 
      <xsl:call-template name="loadDynamicXsl" mode="preprocess_load_xsl" 
     </xsl:if> 
     .... 
    </xsl:stylesheet> 

Biểu định kiểu ext_xslt_container sẽ bao gồm mọi xslts mở rộng. Nó có thể được cập nhật động vào thời gian chạy bằng cách chỉnh sửa nó (như một tài liệu xml), thêm câu lệnh include cho các tệp định kiểu xsl mở rộng. ví dụ

<!-- ext xsl container : ext_xsl_container.xsl--> 
<xsl:stylesheet 
    <xsl:include href="ext_xsl_container.xsl"/> 

    .... 
</xsl:stylesheet 

Tạo một mẫu nhỏ, nói template_load_ext_xsl, với chế độ giao, nói mode = "preprocess_load_xsl" ví dụ

<xsl:template name="loadDynamicXsl" mode="preprocess_load_xsl"> 
    <!-- param: path to the staticall included ext_xsl_container--> 
    <xsl:param name="extXslContainerUrl"/> 
    <!--param: list of dynamically specified extension xsl --> 
    <xsl:param name="extXslUrlList"/> 

    <!-- step 1, [optional ] open the ext Xsl container file --> 
    <!-- step 2 [optional] clear contexts of the ext X -- > 
    <!-- step3 compile a list of include elements, one per each ext Xsl file --> 
    <!-- step 4 [optional] create a union of the include elements created with the content of the xsl container file : ie append content > 
<!-- step 5 : write the union list of incudes to the ext XSL container file --> 
<!-- DONE ---> 

</xsl:template> 

Mẫu sẽ mất như các đối số, tên của ex_xsl_container, và một danh sách các tệp xsl mở rộng (bao gồm cả đường dẫn của chúng) sau đó nó sẽ mở tệp ext_xsl_container dưới dạng tài liệu xml, thêm (tùy chọn chắp thêm hoặc xóa tệp và thêm mã mới) cho từng phần mở rộng: xsl, lưu tệp và thoát ra

Tiếp theo khi bạn chạy xsl chính trong chế độ thi công bình thường, nó willl include template loadDynamicXsl, mà sẽ inturn bao gồm các tập tin XSLT mở rộng specifed tại thời gian chạy

Tạo một kịch bản wrapper đơn giản (ví dụ bash, hoặc shell script) sẽ lấy các đối số cho xslt chính và một tùy chọn để chạy chế độ tiền xử lý. Kịch bản sẽ chỉ gọi xslt chính hai lần, nếu tùy chọn cho chế độ tiền xử lý được bật và bật chế độ tiền xử lý trong lần chạy đầu tiên, tiếp theo là cuộc gọi thứ 2 ở chế độ bình thường

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