2010-10-27 57 views
29

Tôi đang gặp khó khăn khi gói đầu quanh XSLT nhưng tôi nghe nói rằng có thể tách một tệp XML thành nhiều tệp. Về cơ bản tôi muốn sao chép tất cả các phần tử lên đến tệp đầu tiên và sau tệp cuối cùng và sau đó thêm nội dung tệp riêng lẻ cho mỗi tệp đầu ra.Tách XML thành nhiều tệp với XSLT

Ai đó có thể cho tôi một số gợi ý về điều này nếu nó thậm chí có thể?

Cảm ơn,

complete.xml

<rootelem> 
    <elem> 
    <file attr1='1'> 
     <content>content file 1</content> 
    </file> 
    <file attr2='2'> 
     <content>content file 2</content> 
    </file> 
    <file attr3='3'> 
     <content>content file 3</content> 
    </file> 
    </elem> 
</rootelem> 

OUTPUT:

complete_PART1.xml

<rootelem> 
    <elem> 
    <file attr1='1'> 
     <content>content file 1</content> 
    </file> 
    </elem> 
</rootelem> 

complete_PART2.xml

<rootelem> 
    <elem> 
    <file attr2='2'> 
     <content>content file 2</content> 
    </file> 
    </elem> 
</rootelem> 

complete_PART3.xml

<rootelem> 
    <elem> 
    <file attr3='3'> 
     <content>content file 3</content> 
    </file> 
    </elem> 
</rootelem> 
+0

Câu hỏi hay, +1. Xem câu trả lời của tôi để biết hướng dẫn về sự hỗ trợ chuẩn của XSLT (1.0 và 2.0) của kết quả đầu ra nhân sản xuất. –

+0

Tôi có yêu cầu chia các tệp XML lớn thành các tệp nhỏ hơn, nhưng tôi sẽ viết một chương trình để làm (nó cần thăm dò một thư mục và xử lý các tệp lớn hơn x megs) - có rất nhiều loại tệp khác nhau - ví dụ: Tôi không biết cấu trúc XML ở phía trước vì vậy tôi cần một bộ tách chung - điều này có thể được thực hiện với XSLT hay tôi nên sử dụng các công cụ đọc XML .NET không? – Rodney

+0

@ Rodney-- bạn nên xem xét VTD-XML, lý tưởng cho việc xử lý/tách các XML lớn –

Trả lời

14

Hưởng ứng xét của bạn về câu trả lời @ Dimitre của ...

Bạn đã viết,

<xsl:template match="/"> 
    <xsl:for-each select="elem/file"> 
    <xsl:result-document method="xml" href="file_{@id}-output.xml"> 
     <xsl:copy-of select="."/> 
    </xsl:result-document> 
    </xsl:for-each> 
</xsl:template> 

này không hoàn toàn phù hợp với XML của bạn, trong đó có rootelem như một yếu tố ngoài cùng, và nhận xét của bạn nói root là một phần tử ngoài cùng. Bạn có thể muốn cái gì đó như thế này:

<xsl:template match="/root"> 
    <xsl:for-each select="elem/file"> 
    <xsl:result-document method="xml" href="file_{@id}-output.xml"> 
     <root> 
     <xsl:copy-of select="/root/@*" /> 
     <elem> 
      <xsl:copy-of select="../@* | ." /> 
     </elem> 
     </root> 
    </xsl:result-document> 
    </xsl:for-each> 
</xsl:template> 

Bạn có thể nhận được fancier, đang cố gắng sử dụng các yếu tố <xsl:copy>, thay vì kết quả theo nghĩa đen cho rễ và elem, nhưng nó dường như không có giá trị nỗ lực trừ khi họ sẽ khác nhau.

+0

Bạn đang phải Lars, xin lỗi sao chép cẩu thả từ tập tin thực tế. Tôi đã làm một cái gì đó tương tự như những gì bạn có nhưng vấn đề là gốc và elem có các thuộc tính khác nhau mà tôi cần phải duy trì. Nhưng có lẽ tôi bằng cách nào đó có thể sử dụng phụ huynh vẫn cố gắng quấn đầu quanh xslt. –

+0

@Nisse, tôi đã chỉnh sửa câu trả lời để duy trì các thuộc tính của root và elem. Những rắc rối với xsl: copy-of là bạn không thể sửa đổi các phần của những gì được sao chép ... bạn chỉ cần sao chép toàn bộ cây (s) dưới nút (s) bạn chọn. Bạn không thể thêm hoặc bỏ qua bất cứ điều gì. Vì vậy, bạn không thể xsl: copy-of/root hoặc/root/elem. Nhưng nếu bạn xsl: copy-of các thuộc tính cần thiết bạn đang ở trong hình dạng tốt. – LarsH

12

Nó không phải là có thể trong XSLT tinh khiết 1,0 để sản xuất nhiều hơn một tập tin đầu ra. Người ta có thể sử dụng phần tử mở rộng <exslt:document> cho mục đích này.

Trong XSLT 2.0, sử dụng phần tử <xsl:result-document>.

+0

Hi Dimitre, cảm ơn câu trả lời của bạn. Tôi đang sử dụng xsl: result-document ngay bây giờ và nó chia nhỏ tệp nhưng đặt làm phần tử cấp cao nhất. Tuy nhiên, tôi muốn giữ trong mỗi tệp được tạo. Bất kỳ đề xuất về điều đó? < xsl: copy-of select = "." />

+0

tôi có thể biết cách cấu hình phần mở rộng trong VS2010 chuyên nghiệp không . –

+0

@Jeevan: Một (cách duy nhất tôi biết) để đạt được điều này là cài đặt EXSLT-MVP - xem thông báo này của Oleg Tkachenko: http://www.tkachenko.com/blog/archives/000293.html –

2

Nếu bạn muốn sử dụng

<xsl:result-document method="xml" href="file_{@id}-output.xml"> 

từ một cuộc gọi XSLT ANT, bạn cần phải sử dụng 2.0, chỉ cần thêm những điều sau đây gọi ANT của bạn:.

<classpath location="/home/ap/saxon/saxon8.jar" /> 

Và thể chỉ định Phiên bản =" 2.0 " Và tận hưởng chia nhỏ tệp.

+0

@millebbi: Xin lỗi, nhưng có lẽ điều này nên đi trong một câu hỏi khác thực sự hỏi về tích hợp kiến ​​với bộ vi xử lý Saxon XSLT ... –

+0

Vâng nó sẽ đi vào cả hai, bởi vì tôi cũng muốn sử dụng: , tuy nhiên ANT là mặc định bằng cách sử dụng 1.0, với việc thêm tuyên bố ANT này, bạn có thể sử dụng millebii

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