Combine multiple xml files into 1 xml file keeping root node

479 views
Skip to first unread message

disne...@gmail.com

unread,
Jan 21, 2016, 11:36:48 AM1/21/16
to XSLT
I am hoping someone can help me out with this:

I have around 1400 xml files that are all structured the same:

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <call_number>Case FRC 55</call_number>
  <volume>1780-1789</volume>
  <publisher>[Paris : s.n.,</publisher>
  <physical_description>15 p. ; 20 cm.</physical_description>
</metadata>


What I need is from all 1400 xml files, everything including the <metadata> tag and all its children copied into a single xml file so that each set of child elements is wrapped in a metadata parent tag:

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <call_number>Case FRC 55</call_number>
  <publisher>[Paris : s.n.,</publisher>
  <physical_description>15 p. ; 20 cm.</physical_description>
</metadata>
<metadata>
<call_number>CaseFRC11062</call_number>
  <publisher>[Paris] :De l'imprimerie de Baudouin, imprimeur du Corps législatif, place du Carrousel,</publisher>
  <physical_description>14 p. ;20 cm.</physical_description>
</metadata>
<metadata>
 <call_number>CaseFRC10733</call_number>
  <publisher>A Paris :De l'Imprimerie nationale,</publisher>
  <physical_description>88 p. ;20 cm.</physical_description>
</metadata>


I have an XSLT that almost does this, but it doesnt copy the metadata element. So the results are this:

  <call_number>Case FRC 55</call_number>
  <publisher>[Paris : s.n.,</publisher>
  <physical_description>15 p. ; 20 cm.</physical_description>

<call_number>CaseFRC11062</call_number>
  <publisher>[Paris] :De l'imprimerie de Baudouin, imprimeur du Corps législatif, place du Carrousel,</publisher>
  <physical_description>14 p. ;20 cm.</physical_description>

 <call_number>CaseFRC10733</call_number>
  <publisher>A Paris :De l'Imprimerie nationale,</publisher>
  <physical_description>88 p. ;20 cm.</physical_description>



Here is the xslt (this xslt is being used inside the Oxygen software in case that matters) :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml"/>
   
    <xsl:template match="/">
        <xsl:copy>
            <xsl:apply-templates mode="rootcopy"/>
        </xsl:copy>
    </xsl:template>
   
    <xsl:template match="node()" mode="rootcopy">
        <xsl:copy>
            <xsl:variable name="folderURI" select="resolve-uri('.',base-uri())"/>
           
            <xsl:for-each select="collection(concat($folderURI, '?select=*.xml;recurse=yes'))/*/metadata">
                <xsl:apply-templates mode="copy" select="."/>
            </xsl:for-each>
           
        </xsl:copy>
       
    </xsl:template>
   
    <!-- Deep copy template -->
 
    <xsl:template match="node()|@*" mode="copy">
        <xsl:copy>
            <xsl:apply-templates mode="copy" select="@*"/>
            <xsl:apply-templates mode="copy"/>
        </xsl:copy>
    </xsl:template>
   
    <!-- Handle default matching -->
    <xsl:template match="*"/>
  
</xsl:stylesheet>

disne...@gmail.com

unread,
Jan 21, 2016, 11:46:13 AM1/21/16
to XSLT
AN EDIT
the xslt i posted has a bit wrong (i wast trying things out)

Here is the correct one



<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml"/>
   
    <xsl:template match="/">
        <xsl:copy>
            <xsl:apply-templates mode="rootcopy"/>
        </xsl:copy>
    </xsl:template>
   
    <xsl:template match="node()" mode="rootcopy">
        <xsl:copy>
            <xsl:variable name="folderURI" select="resolve-uri('.',base-uri())"/>
           
            <xsl:for-each select="collection(concat($folderURI, '?select=*.xml;recurse=yes'))/*/node()">

dshcs

unread,
Jan 21, 2016, 1:25:52 PM1/21/16
to XSLT
I don't know anything about the collection function, but looking at the code (follows)

<xsl:for-each select="collection(concat($folderURI, '?select=*.xml;recurse=yes'))/*/node()">

collection(concat($folderURI, '?select=*.xml;recurse=yes'))

returns the root node (/) of each XML file, right?

The "/*/node()" pattern that follows would select the first child of the /metadata element, not the /metadata element

I hope that helps

Reply all
Reply to author
Forward
0 new messages