XSL - Subnodes afsplitsen naar aparte bestanden

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen

Afkomstig van [1]:

Hoe het werkt

Er worden twee entiteiten afgesplitst, die meerdere keren voorkomen in het bronbestand, en niet uniek identificeerbaar zijn:

  • Correspondent wordt bv. niet afgesplitst, want daarvan is er maar eentje per record
  • Assignor en Document worden wél afgesplitst en van id voorzien, want daarvan zijn er twee per assignment-record.

Bronbestand parser.py

#!/usr/bin/python

################################################################
# Import
################################################################
#
import os
import lxml.etree as ET

################################################################
# Split off "Assignor"
################################################################
#
# dom = Original XML file
##########################################
#
dom = ET.parse('Assignment.xml')

# Load Assignor-XSLT file
###########################################
#
xslt = ET.parse('Assignor.xsl')

# transform to new file "newdom"
###########################################
#
transform = ET.XSLT(xslt)
newdom = transform(dom)    

# Write "newdom" to file "Output-Assignor.xml"
############################################################
#
xmlfile = open(os.path.join('', 'Output-Assignor.xml'),'wb')
xmlfile.write(newdom)
xmlfile.close()    

################################################################
# Split off "Document"
################################################################
#
xslt = ET.parse('Document.xsl')    
transform = ET.XSLT(xslt)
newdom = transform(dom)

xmlfile = open(os.path.join('', 'Output-Document.xml'),'wb')
xmlfile.write(newdom)
xmlfile.close()

Bronbestand Assignment.xml

<?xml version="1.0" encoding="UTF-8"?>
<assignment>
    <assignment-record>
        <reel-no>28879</reel-no>
        <frame-no>97</frame-no>
        <last-update-date><date>20120903</date></last-update-date>
        <recorded-date><date>20120830</date></recorded-date>
        <page-count>4</page-count>
        <correspondent>
            <name>LEE, HONG, DEGERMAN, KANG & WAIMEY</name>
            <address-1>660 S. FIGUEROA ST., 23RD FL.</address-1>
            <address-2>LOS ANGELES, CA 90017</address-2>
        </correspondent>
        <conveyance-text>ASSIGNMENT OF ASSIGNORS INTEREST (SEE DOCUMENT FOR DETAILS).</conveyance-text>
    </assignment-record>
    <assignors>
        <assignor>
            <name>WOO, SUNGHO</name>
            <execution-date><date>20120806</date></execution-date>
        </assignor>
            <assignor>
                <name>CHOI, JAEYOUNG</name>
                <execution-date><date>20120806</date></execution-date>
        </assignor>
    </assignors>
    <docproperties>
        <property>
            <document-id>
                <country>US</country>
                <doc-number>13277056</doc-number>
                <kind>X0</kind>
                <date>20111019</date>
            </document-id>
            <document-id>
                <country>US</country>
                <doc-number>20120213136</doc-number>
                <kind>A1</kind>
                <date>20120823</date>
            </document-id>
            <title lang="en">SYSTEMS AND METHODS FOR CONTROLLING SENSOR DEVICES IN MOBILE DEVICES</title>
     </property>
    </docproperties>
</assignment>

Bronbestand Assignor.xsl

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

  <xsl:template match="/assignment">
    <xsl:copy>      
      <xsl:apply-templates select="descendant::assignor"/>
    </xsl:copy>
  </xsl:template>  

  <xsl:template match="assignor">
    <xsl:copy>
      <assign_id>
          <xsl:value-of select="ancestor::assignment/assignment-record/reel-no"/>
      </assign_id>
      <xsl:copy-of select="name"/>
      <xsl:copy-of select="execution-date/date"/>        
    </xsl:copy>
  </xsl:template>

</xsl:transform>

Bronbestand Document.xsl

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

  <xsl:template match="/assignment">
    <xsl:copy>
      <xsl:apply-templates select="descendant::document-id"/>
    </xsl:copy>
  </xsl:template>  

  <xsl:template match="document-id">
    <xsl:copy>
      <assign_id>
          <xsl:value-of select="ancestor::assignment/assignment-record/reel-no"/>
      </assign_id>
      <xsl:copy-of select="*"/>        
    </xsl:copy>
  </xsl:template>

</xsl:transform>

Output-bestand Output-Assignor.xml

<?xml version="1.0" encoding="UTF-8"?>
<assignment>
  <assignor>
    <assign_id>28879</assign_id>
    <name>WOO, SUNGHO</name>
    <date>20120806</date>
  </assignor>
  <assignor>
    <assign_id>28879</assign_id>
    <name>CHOI, JAEYOUNG</name>
    <date>20120806</date>
  </assignor>
</assignment>

Output-bestand Output-Document.xml

<?xml version="1.0" encoding="UTF-8"?>
<assignment>
  <document-id>
    <assign_id>28879</assign_id>
    <country>US</country>
    <doc-number>13277056</doc-number>
    <kind>X0</kind>
    <date>20111019</date>
  </document-id>
  <document-id>
    <assign_id>28879</assign_id>
    <country>US</country>
    <doc-number>20120213136</doc-number>
    <kind>A1</kind>
    <date>20120823</date>
  </document-id>
</assignment>

Assignor.xsl - Uitgelegd

Met pseudo-code:

#################################################################################
# Intro
#################################################################################
#
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>


  #################################################################################
  # Copy all assignor-entries
  #################################################################################
  #
  # Select all "assignment" records
  ###################################
  #
  <xsl:template match="/assignment">

    # Copy all assignor-entries
    #########################################################
    #
    <xsl:copy>      
      <xsl:apply-templates select="descendant::assignor"/>
    </xsl:copy>

  # Finish
  ####################################    
  </xsl:template>  


  #################################################################################
  # Add id to these assignor-entries 
  #################################################################################
  #
  # Select all "assignor" records
  ###############################
  #
  # This are probably all the newly copied records, since I can't imagine that
  # it otherwise could copy data data is nested in other data
  #
  <xsl:template match="assignor">
    <xsl:copy>

      # Create tag "assign_id"
      ########################
      #
      # You can tell this is a tag and not a command, as it doesn't include "xsl:"
      #
      <assign_id>

          # Copy value of reel-no, two levels above
          #########################################
          #
          # "value-of" happens within this copy-routine. It copies the value
          # of the given tag, two levels up
          #
          <xsl:value-of select="ancestor::assignment/assignment-record/reel-no"/>

      # Close "assign_id" tag
      #######################
      #
      </assign_id>

      # ???
      ############################
      #
      <xsl:copy-of select="name"/>

      # Change "<execution-date><date>" to "<date>"
      #############################################
      #
      <xsl:copy-of select="execution-date/date"/>        
    </xsl:copy>
  </xsl:template>

</xsl:transform>

Hoe verder met importeren?

  • Uit bestand Assignment.xml, importeer je entiteiten assignment-record
  • Uit bestand Output-Assignor.xml, importeer je entiteiten assignor
  • Uit bestand Output-Document.xml, importeer je entiteiten document.

Verwijder subnodes uit hoofdbestand

Het voorbeeld hiervoor, is precies wat ik zoek, maar dan graag dat de afgesplitste gedeeltes worden verwijderd uit het hoofdbestand: Dat houdt het overzichtelijk. Ik weet namelijk niet vantevoren wat ik allemaal ga tegenkomen aan structuren.

Simpel:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />

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

<xsl:template match="assignor|document-id" />

</xsl:stylesheet>

Bronnen