Skip to content

Repository files navigation

xerparser

Read the contents of a P6 .xer file and convert it into a Python object.

Disclaimers:
It's helpfull if you are already familiar with the mapping and schemas used by P6 during the export process. Refer to the Oracle Documentation for more information regarding how data is mapped to the XER format.
Tested on .xer files exported as versions 15.2 through 19.12.


Install

Windows:

pip install xerparser

Linux/Mac:

pip3 install xerparser

Usage

Import the Xer class from xerparser and pass the contents of a .xer file as an argument. Use the Xer class variable CODEC to set the proper encoding to decode the file.

fromxerparserimportXerfile=r"/path/to/file.xer"withopen(file, encoding=Xer.CODEC, errors="ignore") asf:
file_contents=f.read()
xer=Xer(file_contents)

Do not pass the the .xer file directly as an argument to the Xer class. The file must be decoded and read into a string, which can then be passed as an argument. Or, pass the .xer file into the Xer.reader classmethod, which accepts:

  • str or pathlib.Path objects for files stored locally or on a server.
  • Binary files from requests, Flask, FastAPI, etc...
fromxerparserimportXerfile=r"/path/to/file.xer"xer=Xer.reader(file)

Attributes

The tables stored in the .xer file are accessable as either Global, Project specific, Task specific, or Resource specific:

Global

xer.export_info# export dataxer.activity_code_types# dict of ACTVTYPE objectsxer.activity_code_values# dict of ACTVCODE objectsxer.calendars# dict of all CALENDAR objectsxer.financial_periods# dict of FINDATES objectsxer.notebook_topics# dict of MEMOTYPE objectsxer.projects# dict of PROJECT objectsxer.project_code_types# dict of PCATTYPE objectsxer.project_code_values# dict of PCATVAL objectsxer.tasks# dict of all TASK objectsxer.relationships# dict of all TASKPRED objectsxer.resources# dict of RSRC objectsxer.resource_rates# dict of RSRCRATE objectsxer.udf_types# dict of UDFTYPE objectsxer.wbs_nodes# dict of all PROJWBS objects

Project Specific

# Get first projectproject=list(xer.projects.values())[0]
project.activity_codes# list of project specific ACTVTYPE objectsproject.calendars# list of project specific CALENDAR objectsproject.project_codes# dict of PCATTYPE: PCATVAL objectsproject.tasks# list of project specific TASK objectsproject.relationships# list of project specific TASKPRED objectsproject.resources# lest of project specific TASKRSRC objectsproject.user_defined_fields# dict of `UDFTYPE`: `UDF Value` pairs project.wbs_nodes# list of project specific PROJWBS objects

WBS Specific

# Get projects root wbs nodewbs_node=project.wbs_rootwbs_node.children# list of child PROJWBS objectswbs_node.project# PROJECT the WBS node belongs towbs_node.tasks# list of TASK objects assigned directly to WBS nodewbs_node.all_tasks# list of TASK objects under the WBS nodewbs_node.user_defined_fields# dict of `UDFTYPE`: `UDF Value` pairs 

Task Specific

# Get first tasktask=project.tasks[0]
task.activity_codes# dict of ACTVTYPE: ACTVCODE objectstask.memos# list of TASKMEMO objectstask.periods# list of TASKFIN objectstask.resources# dict of TASKRSRC objectstask.user_defined_fields# dict of `UDFTYPE`: `UDF Value` pairs 

Resource Specific

# Get first task resourceresource=list(task.resources.values())[0]
resource.periods# list of TRSRCFIN objectsresource.user_defined_fields# dict of `UDFTYPE`: `UDF Value` pairs 

Error Checking

Sometimes the xer file is corrupted during the export process. If this is the case, a CorruptXerFile Exception will be raised during initialization. A list of the errors can be accessed from the CorruptXerFile Exception, or by using the find_xer_errors function.

Option 1 - errors attribute of CorruptXerFile exception (preferred)

fromxerparserimportXer, CorruptXerFilefile=r"/path/to/file.xer"try:
xer=Xer.reader(file)
exceptCorruptXerFilease:
forerrorine.errors:
print(error)

Option 2 - find_xer_errors function

fromxerparserimportparser, file_reader, find_xer_errorsfile=r"/path/to/file.xer"xer_data=parser(file_reader(file))
file_errors=find_xer_errors(xer_data)
forerrorinfile_errors:
print(error)

Errors

  • Minimum required tables - an error is recorded if one of the following tables is missing:

    • CALENDAR
    • PROJECT
    • PROJWBS
    • TASK
  • Required table pairs - an error is recorded if Table 1 is included but not Table 2:

    Table 1Table 2Notes
    TASKFINFINDATESFinancial Period Data for Task
    TRSRCFINFINDATESFinancial Period Data for Task Resource
    TASKRSRCRSRCResource Data
    TASKMEMOMEMOTYPENotebook Data
    ACTVCODEACTVTYPEActivity Code Data
    TASKACTVACTVCODEActivity Code Data
    PCATVALPCATTYPEProject Code Data
    PROJPCATPCATVALProject Code Data
    UDFVALUEUDFTYPEUser Defined Field Data
  • Non-existent calendars assigned to tasks.

  • Non-existent resources assigned to task resources.

About

Parse the contents of a P6 .xer file into a Python object

Topics

Resources

Stars

37 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages