2010-12-13 17 views
5

Мне нужно разбить следующий XML-файл на основе заданного значения, для этого примера можно предположить, что я хочу ограничить узел «Item» тремя (3) в каждом файл создан.Разделить XML-файл на несколько файлов на основе порогового значения

Вот пример входного 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> 

Нужный выход на основе порогового значения 3, будет три файла, два из которых содержат 3 «Item», и последний один, содержащий остальные «предметы», которые будут едины.

Вот пример моего XSLT, который позволяет мне разделить их на каждый элемент, что приводит к семи отдельным файлам, однако я хочу ограничить размер файла на основе определенного предела «Item», узел на файл.

<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

Хороший вопрос, +1. См. Мой ответ для простого решения. –

ответ

6

Эта таблица стилей:

<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> 

Выход:

<?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

Спасибо Алехандро, что сделал эту работу. – Brian

+0

@Brian: Добро пожаловать. – 2010-12-14 12:34:34

-1

Вы можете реализовать счетчик, который объявлен вне вашего цикла. Когда счетчик достигнет 3, сбросьте его и установите новое имя файла. В противном случае добавьте и добавьте существующее имя файла.

0

Это преобразование:

<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> 

при нанесении на поставленном 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> 

производит хотел три 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 

Обратите внимание:

  1. Это простое применение шаблона правила идентичности.

  2. Каждого Item запуск нового файл сопоставляется и это вызывает перенос в верхнем элементе, обработка самого по себе, а следующему $ pSplitNum -1 (или то, что осталось в последней группе), и выводит это как единый результирующий документ (файл).

  3. Имя каждого файла, созданный в: «FileX-y.xml», где x и y являются начальными и конечными индексами в Item элементов, записанных в файле.

  4. Каждый Item новый, не запустив новый файл пустым шаблоном. Такие элементы обрабатываются в режиме «копирования».

Смежные вопросы