2010-12-13 30 views
5

Tôi cần chia tệp XML sau dựa trên giá trị được xác định trước, cho ví dụ này, giả sử tôi muốn giới hạn nút "Mục" thành ba (3) trong mỗi giá trị tệp đã được tạo.Tách tệp XML thành nhiều tệp dựa trên giá trị ngưỡng

Dưới đây là một ví dụ tập tin đầu vào XML:

<Items> 
    <Item> 
    <Title>Title 1</Title> 
    <DueDate>01-02-2008</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 2</Title> 
    <DueDate>01-02-2009</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 3</Title> 
    <DueDate>01-02-2010</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 4</Title> 
    <DueDate>01-02-2011</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 5</Title> 
    <DueDate>01-02-2012</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 6</Title> 
    <DueDate>01-02-2013</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 7</Title> 
    <DueDate>01-02-2013</DueDate> 
    </Item> 
</Items> 

Các đầu ra mong muốn dựa trên giá trị ngưỡng 3, sẽ là ba tác phẩm, hai trong số đó chứa 3 "Item", và người cuối cùng có chứa còn lại "các mục", sẽ là một mục. Đây là một mẫu XSLT của tôi cho phép tôi chia nhỏ chúng cho từng mục, kết quả thành bảy tệp riêng biệt, tuy nhiên, điều tôi mong muốn là giới hạn kích thước của tệp dựa trên giới hạn nhất định của "Mục" nút trên mỗi tệp.

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

<xsl:output method="xml" indent="yes" name="xml" /> 

<xsl:template match="/"> 

<xsl:for-each select="//Item"> 
    <xsl:variable name="nTitle" select="Title"/> 
    <xsl:variable name="filename" select="concat('Items\',$nTitle,'-','.xml')" /> 
    <xsl:value-of select="$filename" /> 
    <xsl:result-document href="{$filename}" format="xml"> 
     <xsl:copy-of select="."/> 
    </xsl:result-document> 
</xsl:for-each> 

</xsl:template> 
</xsl:stylesheet> 
+0

Câu hỏi hay, +1. Xem câu trả lời của tôi cho một giải pháp đơn giản. –

Trả lời

6

kiểu này:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:param name="pItemsNumber" select="3"/> 
    <xsl:template match="Items"> 
     <xsl:for-each-group select="Item" 
          group-adjacent="(position()-1) idiv $pItemsNumber"> 
      <xsl:result-document href="Items\{current-grouping-key()}.xml"> 
       <Items> 
        <xsl:copy-of select="current-group()"/> 
       </Items> 
      </xsl:result-document> 
     </xsl:for-each-group> 
    </xsl:template> 
</xsl:stylesheet> 

Output:

<?xml version="1.0" encoding="UTF-8"?> 
<Items> 
    <Item> 
     <Title>Title 1</Title> 
     <DueDate>01-02-2008</DueDate> 
    </Item> 
    <Item> 
     <Title>Title 2</Title> 
     <DueDate>01-02-2009</DueDate> 
    </Item> 
    <Item> 
     <Title>Title 3</Title> 
     <DueDate>01-02-2010</DueDate> 
    </Item> 
</Items> 

<?xml version="1.0" encoding="UTF-8"?> 
<Items> 
    <Item> 
     <Title>Title 4</Title> 
     <DueDate>01-02-2011</DueDate> 
    </Item> 
    <Item> 
     <Title>Title 5</Title> 
     <DueDate>01-02-2012</DueDate> 
    </Item> 
    <Item> 
     <Title>Title 6</Title> 
     <DueDate>01-02-2013</DueDate> 
    </Item> 
</Items> 

<?xml version="1.0" encoding="UTF-8"?> 
<Items> 
    <Item> 
     <Title>Title 7</Title> 
     <DueDate>01-02-2013</DueDate> 
    </Item> 
</Items> 

Edit: Oops!

+0

Cảm ơn Alejandro, đã thực hiện công việc. – Brian

+0

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

-1

Bạn có thể triển khai bộ đếm được khai báo ngoài vòng lặp của mình. Khi bộ đếm truy cập 3, hãy đặt lại và đặt tên tệp mới. Nếu không, hãy tăng và thêm vào tên tệp hiện có.

0

chuyển đổi này:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:param name="pSplitNum" select="3"/> 

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

<xsl:template match="Item[position() mod $pSplitNum eq 1]"> 
    <xsl:result-document href= 
    "file{position()}-{min((position()+$pSplitNum -1, count(/*/Item)))}.xml"> 
    <Items> 
     <xsl:call-template name="identity"/> 
     <xsl:apply-templates mode="copy" select= 
     "following-sibling::Item[position() lt $pSplitNum]"/> 
    </Items> 
    </xsl:result-document> 
</xsl:template> 
<xsl:template match="/*"><xsl:apply-templates/></xsl:template> 
<xsl:template match="Item[position() mod $pSplitNum ne 1]"/> 
</xsl:stylesheet> 

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

<Items> 
    <Item> 
    <Title>Title 1</Title> 
    <DueDate>01-02-2008</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 2</Title> 
    <DueDate>01-02-2009</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 3</Title> 
    <DueDate>01-02-2010</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 4</Title> 
    <DueDate>01-02-2011</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 5</Title> 
    <DueDate>01-02-2012</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 6</Title> 
    <DueDate>01-02-2013</DueDate> 
    </Item> 
    <Item> 
    <Title>Title 7</Title> 
    <DueDate>01-02-2013</DueDate> 
    </Item> 
</Items> 

tạo ra muốn ba file xml:

Saxon 9.1.0.5J from Saxonica 
Java version 1.6.0_22 
Stylesheet compilation time: 645 milliseconds 
Processing file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml 
Building tree for file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml using class net.sf.saxon.tinytree.TinyBuilder 
Tree built in 10 milliseconds 
Tree size: 38 nodes, 119 characters, 0 attributes 
Loading net.sf.saxon.event.MessageEmitter 
Writing to file:/C:/Program%20Files/Java/jre6/bin/file1-3.xml 
Writing to file:/C:/Program%20Files/Java/jre6/bin/file4-6.xml 
Writing to file:/C:/Program%20Files/Java/jre6/bin/file7-7.xml 
Execution time: 101 milliseconds 
Memory used: 11453088 
NamePool contents: 20 entries in 20 chains. 6 prefixes, 7 URIs 

Do lưu ý:

  1. Đây là một ứng dụng đơn giản của mô hình cai trị bản sắc.

  2. Mỗi Item bắt đầu một tập tin mới là lần xuất hiện và nó gây ra các gói trong một yếu tố hàng đầu, chế biến riêng của mình và tiếp theo $ pSplitNum -1 (hoặc những gì còn lại trong nhóm cuối cùng), và xuất này như một một tài liệu kết quả (tệp).

  3. Tên của mỗi tập tin được tạo ra là: "filex-y.xml", nơi xy là thời gian bắt đầu và chỉ số kết thúc của Item yếu tố được viết trong file.

  4. Mọi tệp Item không bắt đầu tệp mới sẽ bị xóa bởi mẫu phù hợp trống. Các yếu tố như vậy được xử lý trong chế độ "sao chép".

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