Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
881 views
in Technique[技术] by (71.8m points)

xslt - Split one out-file into multiple xmls after n elements

I am using a 3rd party software to generate an XML-file. This software allows to use a post-processor in form of XSLT (2.0).

My output files are rather huge, often reaching multiple hundred MB and several million of lines. I want to chunk my output files and have 1 file after each (lets say 10 products) instead of all in one file.

I found a smiliar thread here: Split one XML file to multiple XML File with XSLT but since I'm completly new to XSLT, I can't figure out on how to give a specific range at which the files will be splitted. I assume xsl:for-each select="document/file"> from the given example is the expression where to look, but I'm not certain either.

A simple XML looks a bit like this:

<Products>
  <Product ID="123" UserType="ITEM">
    <Name>First Product</Name>
    <Values>
      <Value AttributeID="someAttribute">foo</Value>
      <Value AttributeID="AnotherAttribute">bar</Value>
    </Values>
  </Product>
  <Product ID="456" UserType="ITEM">
    <Name>Second Product</Name>
    <Values>
      <Value AttributeID="someAttribute">foo</Value>
      <Value AttributeID="AnotherAttribute">bar</Value>
    </Values>
  </Product>
</Products>

As mentioned above, there are multiple thousands of products and for the sake of a clean overview, I left out the nodes before and after the <Products>-node.

How can I split my one given output-file to N files, which are split after lets say 10 products?

question from:https://stackoverflow.com/questions/65898634/split-one-out-file-into-multiple-xmls-after-n-elements

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Assuming the Products element is a child of the root element you could use e.g.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  expand-text="yes">
  
  <xsl:param name="size" as="xs:integer" select="2"/>

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

  <xsl:template match="/*">
    <xsl:for-each-group select="*" group-adjacent="boolean(self::Products)">
      <xsl:choose>
        <xsl:when test="not(current-grouping-key()) and position() = 1">
          <xsl:result-document href="headers.xml">
            <Root>
              <xsl:copy-of select="current-group()"/>
            </Root>
          </xsl:result-document>
        </xsl:when>
        <xsl:when test="current-grouping-key()">
          <xsl:for-each-group select="current-group()/Product" group-by="(position() - 1) idiv $size">
            <xsl:result-document href="chunk-{position()}.xml">
              <Products>
                <xsl:copy-of select="current-group()"/>
              </Products>
            </xsl:result-document>
          </xsl:for-each-group>
        </xsl:when>
        <xsl:when test="not(current-grouping-key()) and position() = last()">
          <xsl:result-document href="footers.xml">
            <Root>
              <xsl:copy-of select="current-group()"/>
            </Root>
          </xsl:result-document>
        </xsl:when>
      </xsl:choose>
    </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...