2011-02-10 27 views
6

Tôi đã được giao nhiệm vụ tổng hợp một cuốn sách (sử dụng XSL FO) từ một số tệp XML, giờ tôi đang cố gắng đếm số liệu cuốn sách này (đánh số đơn giản, không reset vào chương hoặc bất cứ điều gì), cách tiếp cận ngây thơ của tôi đã làm điều nàySố XSLT chỉ tính các trường hợp trong tệp hiện tại của tài liệu nhiều tệp

<xsl:template match="figure"> 
    <fo:block xsl:use-attribute-sets="figure"> 
    .. stuff to deal with images .. 
    <fo:block xsl:use-attribute-sets="figure-caption"> 
     Figure <xsl:number level="any"/>: <xsl:apply-templates/> 
    </fo:block> 
    <fo:block xsl:use-attribute-sets="figure-caption"> 
</xsl:template> 

tôi có một file XML tổng hợp mà lựa chọn các tập tin để sử dụng bằng cách sử dụng document() chức năng như vậy:

<xsl:template match="include"> 
    <xsl:apply-templates select="document(@src)"/> 
</xsl:template> 

Bây giờ, sự cố của tôi là number dường như đã thay đổi ays chỉ đếm các cá thể trong tệp hiện tại, không phải là những gì tôi muốn (hiện tại, chỉ có một hoặc hai hình ảnh cho mỗi tệp, dẫn đến tất cả các số liệu là 'Hình 1' hoặc 'Hình 2').

Tôi đã xem xét hai phương pháp tiếp cận, cả về bản chất là XSLT hai lần. Thứ nhất, cách tiếp cận đơn giản, tạo ra một XML trung gian chứa toàn bộ cuốn sách bằng cách sử dụng một biến đổi nhận dạng, mà tôi không muốn làm vì những lý do khác.

Thứ hai, sử dụng node-set() mở rộng, mà tôi đã cố gắng như thế này

<xsl:template match="include"> 
    <xsl:apply-templates select="ext:node-set(document(@src))"/> 
</xsl:template> 

nhưng điều này tạo ra kết quả tương tự.

Bất kỳ ý tưởng nào? Có lẽ một cái gì đó không phải là một sự chuyển đổi hai vượt qua? Mọi sự trợ giúp sẽ rất được trân trọng.

+0

Tốt câu hỏi, 1. Xem câu trả lời của tôi cho một cuộc thảo luận về hai cách tiếp cận, một khuyến nghị và giải thích rõ ràng cho đề xuất này. –

+0

+1. Đó là một câu hỏi thú vị. – Flack

+0

+1 Thật vậy, một câu hỏi hay. –

Trả lời

3

Cách tiếp cận hai đường là phương pháp hợp lý và mạnh mẽ hơn.

Phương pháp một lần rất khó khăn. Một có thể cung cấp một biểu thức trong thuộc tính value của <xsl:number> và điều này có thể được sử dụng để tính tổng "số địa phương" với số tích lũy tối đa cho đến nay từ tất cả các tài liệu trước đó.

Tuy nhiên, điều này đòi hỏi phải sắp xếp các tài liệu (đó là một cái gì đó xấu trong một ngôn ngữ chức năng) và điều này chỉ hoạt động cho một chương trình đánh số căn hộ. Trong trường hợp đánh số phân cấp được sử dụng (3.4.2), tôi không thấy một cách dễ dàng để tiếp tục từ số lượng tối đa của một tài liệu trước đó.

Do những cân nhắc này, tôi chắc chắn sẽ hợp nhất tất cả tài liệu thành một trước khi đánh số.

+0

+1. Tôi hoàn toàn đồng ý. – Flack

+0

+1 Đối số. –

0

Bạn có thể sử dụng tài liệu XML phụ trợ để theo dõi số hình mới nhất và tải tệp đó dưới dạng tài liệu từ biểu định kiểu của bạn. Hoặc, nếu bạn không muốn quản lý hai tệp đầu ra từ cùng một biểu định kiểu (đầu ra FOP "thực" và bộ đếm hình), bạn có thể tải tệp FOP của chương trước và tìm MAX của chú thích hình.

Hoặc bạn có thể vượt qua số hình cuối cùng làm tham số với số không mặc định và chuyển tham số trên dòng lệnh. Giá trị của tham số này xuất phát từ việc phân tích cú pháp của tham số trước đó trong thứ tự tài liệu kết quả tăng dần.

Tất cả các lựa chọn thay thế này giả sử bạn đang chạy các phép biến đổi theo thứ tự trong thứ tự tăng dần của tài liệu nguồn. Một giải pháp có cấu trúc và mạnh mẽ hơn là quản lý các phần tài liệu ngang như chỉ mục, mục lục và bảng số liệu trong nhiều tài liệu FO riêng biệt sẽ được tạo trong lần chạy thứ hai chạy với XSLT của riêng chúng.

0

Tôi nghĩ rằng tôi sẽ thực hiện việc chuẩn bị kết quả cung cấp thông tin tóm tắt về tất cả các tài liệu trong một tệp XML và sau đó sử dụng thông tin này làm đầu vào thứ cấp cho phép tính số. Thông tin tóm tắt trong trường hợp của bạn có thể chỉ là số lượng bao nhiêu số liệu mà mỗi tài liệu chứa, nhưng trong nhiều trường hợp, có thể hữu ích để giữ thông tin khác cũng như ID của các phần sẽ hoạt động như mục tiêu của siêu liên kết.

2

Tôi cũng sẽ sử dụng phép chuyển đổi hai pha. Nhưng chỉ để cho vui, với một include mức và không có sự lặp lại, kiểu này:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:variable name="vIncludes" select="//include"/> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="include"> 
     <xsl:apply-templates select="document(@src)"/> 
    </xsl:template> 
    <xsl:template match="picture"> 
     <xsl:variable name="vRoot" select="generate-id(/)"/> 
     <xsl:variable name="vInclude" 
         select="$vIncludes[ 
           $vRoot = generate-id(document(@src)) 
           ]"/> 
     <xsl:copy> 
      <xsl:value-of 
       select="count(
          document(
           (.|$vInclude)/preceding::include/@src 
          )//picture | 
          (.|$vInclude)/preceding::picture 
         ) + 1"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

Với đầu vào này:

<master> 
    <include src="child3.xml"/> 
    <block> 
     <include src="child1.xml"/> 
     <picture/> 
    </block> 
    <include src="child2.xml"/> 
    <picture/> 
</master> 

Và 'child1.xml'

<child1> 
    <picture/> 
</child1> 

Và 'child2 .xml '

<child2> 
    <picture/> 
</child2> 

Và 'child3.xml'

<child3> 
    <picture/> 
</child3> 

Output:

<master> 
    <child3> 
     <picture>1</picture> 
    </child3> 
    <block> 
     <child1> 
      <picture>2</picture> 
     </child1> 
     <picture>3</picture> 
    </block> 
    <child2> 
     <picture>4</picture> 
    </child2> 
    <picture>5</picture> 
</master> 
+0

+1 để biết ví dụ. – Flack

+0

+1. Điều đó thực sự rất thú vị, phải mất một lúc để quấn quanh đầu tôi, nên tôi nghĩ tôi sẽ xem xét chuyển đổi hai bước thay vì ... =) – falstro

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