Reading and Writing Files
Besides working with strings directly (see Parsing Messages), this package can read messages from files on disk and serialize them back to the XML and KVN formats defined by CCSDS 502.0-B-3.
Reading From a File
Assume the variable sample_file holds the path to a file containing a CCSDS-compliant OMM, in either the XML or the KVN format. We can load it with read_omm:
julia> omm = read_omm(sample_file)OrbitMeanElementsMessage: Header Comment : GENERATED VIA SPACE-TRACK.ORG API Creation Date : 2025-12-30T23:36:37 Originator : 18 SPCS Metadata Object Name : AMAZONIA 1 Object ID : 2021-015A Center Name : EARTH Ref. Frame : TEME Time System : UTC Mean Element Theory : SGP4 Data └─ Mean Keplerian Elements Epoch : 2025-12-30T18:12:04.533984 Mean Motion : 14.40772474 rev/day Eccentricity : 0.0001124 Inclination : 98.3721° RA of Asc. Node : 75.0877° Arg. of Pericenter : 97.3772° Mean Anomaly : 262.7545°
If the file may contain several messages, use read_omms to retrieve all OMMs as a vector:
julia> omms = read_omms(sample_file)1-element Vector{OrbitMeanElementsMessage}: OMM: AMAZONIA 1 [2021-015A] (Epoch = 2025-12-30T18:12:04.533984)
To read a generic Orbit Data Message — which may be a single message or a Navigation Data Message (NDM) bundling several messages — use read_odm:
julia> odm = read_odm(sample_file)1-element Vector{OrbitDataMessage}: OMM: AMAZONIA 1 [2021-015A] (Epoch = 2025-12-30T18:12:04.533984)
All functions simply read the file contents and forward them to the corresponding parsing function, so the input format is detected automatically and the return values follow the same rules described in Parsing Messages.
Writing to a File
Given an OrbitMeanElementsMessage object, we can serialize it with write_omm. The function accepts a file path, inferring the output format from the extension (case-insensitive): .kvn selects the KVN format, whereas any other extension selects the XML format. The file_type keyword (:auto, :xml, or :kvn) overrides the inference:
write_omm("amazonia_1.xml", omm) # XML output.
write_omm("amazonia_1.kvn", omm) # KVN output.
write_omm("amazonia_1.omm", omm; file_type = :kvn) # KVN output with another extension.The function also receives an IO stream, which makes it easy to inspect the output in memory. In this case, the default output format is XML:
julia> io = IOBuffer();julia> write_omm(io, omm)julia> print(String(take!(io)))<?xml version="1.0" encoding="UTF-8"?> <omm id="CCSDS_OMM_VERS" version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://sanaregistry.org/files/ndmxml_unqualified/ndmxml-4.0.0-master-4.0.xsd"> <header> <COMMENT>GENERATED VIA SPACE-TRACK.ORG API</COMMENT> <CREATION_DATE>2025-12-30T23:36:37.000000000</CREATION_DATE> <ORIGINATOR>18 SPCS</ORIGINATOR> </header> <body> <segment> <metadata> <OBJECT_NAME>AMAZONIA 1</OBJECT_NAME> <OBJECT_ID>2021-015A</OBJECT_ID> <CENTER_NAME>EARTH</CENTER_NAME> <REF_FRAME>TEME</REF_FRAME> <TIME_SYSTEM>UTC</TIME_SYSTEM> <MEAN_ELEMENT_THEORY>SGP4</MEAN_ELEMENT_THEORY> </metadata> <data> <meanElements> <EPOCH>2025-12-30T18:12:04.533984000</EPOCH> <MEAN_MOTION>14.40772474</MEAN_MOTION> <ECCENTRICITY>0.0001124</ECCENTRICITY> <INCLINATION>98.3721</INCLINATION> <RA_OF_ASC_NODE>75.0877</RA_OF_ASC_NODE> <ARG_OF_PERICENTER>97.3772</ARG_OF_PERICENTER> <MEAN_ANOMALY>262.7545</MEAN_ANOMALY> </meanElements> </data> </segment> </body> </omm>
The same message in the KVN format:
julia> write_omm(io, omm; file_type = :kvn)julia> print(String(take!(io)))CCSDS_OMM_VERS = 3.0 COMMENT GENERATED VIA SPACE-TRACK.ORG API CREATION_DATE = 2025-12-30T23:36:37.000000000 ORIGINATOR = 18 SPCS OBJECT_NAME = AMAZONIA 1 OBJECT_ID = 2021-015A CENTER_NAME = EARTH REF_FRAME = TEME TIME_SYSTEM = UTC MEAN_ELEMENT_THEORY = SGP4 EPOCH = 2025-12-30T18:12:04.533984000 MEAN_MOTION = 14.40772474 [rev/day] ECCENTRICITY = 0.0001124 INCLINATION = 98.3721 [deg] RA_OF_ASC_NODE = 75.0877 [deg] ARG_OF_PERICENTER = 97.3772 [deg] MEAN_ANOMALY = 262.7545 [deg]
Writing Several Messages
write_omm also accepts a vector of messages. In the XML format, all messages are wrapped inside a single Navigation Data Message (<ndm>) root element, whereas in the KVN format they are written sequentially, each one starting at its CCSDS_OMM_VERS keyword:
omms = [omm1, omm2, omm3]
write_omm("catalog.xml", omms)
write_omm("catalog.kvn", omms)The write_odm function provides the same functionality for generic Orbit Data Messages, always using the NDM/XML output:
write_odm("catalog.xml", omms)This is convenient, for example, to persist the full set of messages returned by one of the online fetchers.
OMM messages are always written with version 3.0, regardless of the version stored in the parsed message. NanoDate values are written with nine fractional digits, preserving nanosecond precision. Optional sections (spacecraft parameters, TLE-related parameters, the covariance matrix, and user-defined parameters) are only written when the corresponding fields are present in the message.