Is there an example showing how the geogebra.xml file (found in Geogebra's *.ggb file) is structured so I can write a file with custom data using another program?

Version: Geogebra Classic 6 via Firefox web-browser session

1

There are 1 answers

0
Eric Marceau On

I am posting this here to make life easier for others by offering a simplistic and generic approach to the problem.

Geogebra's *.ggb file is a zip file which can be renamed to *.zip to simplify handling as a zip file.

Examining that zip file, the contents are reported as:

$ unzip -l Freq_30.zip
Archive:  Freq_30.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
    11839  2023-10-06 09:50   geogebra_thumbnail.png
       23  2023-10-06 09:50   geogebra_javascript.js
     9860  2023-10-06 09:50   geogebra_defaults2d.xml
     4497  2023-10-06 09:50   geogebra_defaults3d.xml
    26668  2023-10-06 09:50   geogebra.xml
---------                     -------
    52887                     5 files
$ 

As we can see, there are a number of XML files within that zip file. All those files can be extracted into a folder for manipulation. I strongly recommend that you make a duplicate copy of these files as a backup before manipulating the contents.

After reviewing those files, I concluded that the only one that contains actual geometry constructs (unrelated to viewing, orientation or GUI) is is the geogebra.xml file.

I created a very simplistic *.ggb model with minimal elements to be able to unravel the puzzle. For my simplified model, I was able to "explode" the geogebra.xml file into (as I perceived it) logical components. These were:

-rw-rw-r-- 1 user group 5012 Oct  9 21:08 geogebra.xml__01_HEADER
-rw-rw-r-- 1 user group 1587 Oct  9 21:04 geogebra.xml__02_GEOMETRY_POINT
-rw-rw-r-- 1 user group 1722 Oct  9 21:05 geogebra.xml__03_GEOMETRY_SEGMENT
-rw-rw-r-- 1 user group 1929 Oct  9 21:06 geogebra.xml__04_GEOMETRY_FACE
-rw-rw-r-- 1 user group  288 Oct  9 21:06 geogebra.xml__05_TRAILER

The contents of my finalized versions for each of these are included later (below) for study/review/reference.

After manipulating these files to my satisfaction, I then reconstituted the geogebra.xml file from the newly-created parts (simple cat command in Linux).

Having kept the other files that formed the original *.ggb file, I created a new *.ggb file with the appropriate form of the zip command. The *.zip file was then renamed to the *.ggb form expected by Geogebra.

Using the File/Open options in Geogebra, I was able to load the new file successfully with the modified geometry and continue manipulating that without problems.

I created a simple script (Geogebra__BuildCustomModel.sh) to simplify the rebuild of the *.gbb file from the component parts, namely:

#!/bin/sh

####################################################################################################
###
### Script to intelligently build custom Geogebra *.ggb file from supplied component files
### which are compliant with Geogebra XML object definition structures.
###
### Author:  Eric Marceau, Ottawa, Canada
### Date:    2023-10-10
###
####################################################################################################

xmlFile="geogebra.xml"      ; rm -f "${xmlFile}"
zipFile="geogebra_BUILT.zip"    ; rm -f "${zipFile}"
outFile="geogebra_BUILT.ggb"    ; rm -f "${outFile}"

echo "\n Evaluating input files ..."
abandon=0
for file in \
    geogebra.xml__01_HEADER \
    geogebra.xml__02_GEOMETRY_POINT \
    geogebra.xml__03_GEOMETRY_SEGMENT \
    geogebra.xml__04_GEOMETRY_FACE \
    geogebra.xml__05_TRAILER
do
    if [ -s "${file}" ]
    then
        ls -l "${file}" | awk '{ printf("\t [GOOD] %s\n", $0 ) ; }'
    else
        if [ -f "${file}" ]
        then
            echo "${file}" | awk '{ printf("\t [EMPT] %s\n", $0 ) ; }'
        else
            echo "${file}" | awk '{ printf("\t [MISS] %s\n", $0 ) ; }'
        fi
        abandon=1
    fi
    if [ ${abandon} -eq 1 ]
    then
        echo "\n\t Missing mandatory component(s) for creating Geogebra XML file."
        echo   "\t UNABLE to create the Geogebra model.\n"
        exit 1
    fi
done

cat \
    geogebra.xml__01_HEADER \
    geogebra.xml__02_GEOMETRY_POINT \
    geogebra.xml__03_GEOMETRY_SEGMENT \
    geogebra.xml__04_GEOMETRY_FACE \
    geogebra.xml__05_TRAILER \
    > "${xmlFile}"

if [ -s "${xmlFile}" ]
then
    echo "\n\t Geogebra XML file was successfully created:"
    ls -l "${xmlFile}" | awk '{ printf("\n\t %s\n", $0 ) ; }'
else
    echo "\n\t Geogebra XML file was NOT created."
    echo   "\t UNABLE to create the Geogebra model.\n"
    exit 1
fi

zip -Z store \
    "${zipFile}" \
    geogebra_thumbnail.png \
    geogebra_javascript.js \
    geogebra_defaults2d.xml \
    geogebra_defaults3d.xml \
    geogebra.xml

if [ -s "${zipFile}" ]
then
    echo "\n\t Geogebra ZIPped XML file was successfully created:"
    ls -l "${zipFile}" | awk '{ printf("\n\t %s\n", $0 ) ; }'
    unzip -l "${zipFile}"

    echo "\n\t ZIP file renamed as Geogebra model file:"
    mv "${zipFile}" "${outFile}"
    ls -l "${outFile}" | awk '{ printf("\n\t %s\n", $0 ) ; }'
fi

Here is a log for a "rebuild" session:

$ ./Geogebra__BuildCustomModel.sh

 Evaluating input files ...
     [GOOD] -rw-rw-r-- 1 user group 5012 Oct  9 21:08 geogebra.xml__01_HEADER
     [GOOD] -rw-rw-r-- 1 user group 1587 Oct  9 21:04 geogebra.xml__02_GEOMETRY_POINT
     [GOOD] -rw-rw-r-- 1 user group 1722 Oct  9 21:05 geogebra.xml__03_GEOMETRY_SEGMENT
     [GOOD] -rw-rw-r-- 1 user group 1929 Oct  9 21:06 geogebra.xml__04_GEOMETRY_FACE
     [GOOD] -rw-rw-r-- 1 user group  288 Oct  9 21:06 geogebra.xml__05_TRAILER

     Geogebra XML file was successfully created:

     -rw-rw-r-- 1 user group 10538 Oct 10 09:05 geogebra.xml
  adding: geogebra_thumbnail.png (stored 0%)
  adding: geogebra_javascript.js (stored 0%)
  adding: geogebra_defaults2d.xml (stored 0%)
  adding: geogebra_defaults3d.xml (stored 0%)
  adding: geogebra.xml (stored 0%)

     Geogebra ZIPped XML file was successfully created:

     -rw-rw-r-- 1 user group 53340 Oct 10 09:05 geogebra_BUILT.zip
Archive:  geogebra_BUILT.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
    27718  2023-10-09 20:30   geogebra_thumbnail.png
       23  2023-10-09 20:30   geogebra_javascript.js
     9772  2023-10-09 20:30   geogebra_defaults2d.xml
     4423  2023-10-09 20:30   geogebra_defaults3d.xml
    10538  2023-10-10 09:05   geogebra.xml
---------                     -------
    52474                     5 files

     ZIP file renamed as Geogebra model file:

     -rw-rw-r-- 1 user group 53340 Oct 10 09:05 geogebra_BUILT.ggb
$ 

The resulting model seen in Geogebra is as follows: enter image description here

Here are the contents of the 5 component files for my simplified Geogebra model.

geogebra.xml__01_HEADER:

<?xml version="1.0" encoding="utf-8"?>

<!--==============================================================================-->
<!--============================   START-of-HEADER   =============================-->
<!--==============================================================================-->

<geogebra format="5.0" version="5.2.805.0" app="classic" platform="w" id="dbae37b5-9aed-4148-8d01-be615e0b4b06"  xsi:noNamespaceSchemaLocation="http://www.geogebra.org/apps/xsd/ggb.xsd" xmlns="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<gui>
    <window width="1029" height="641" />
    <perspectives>
<perspective id="tmp">
    <panes>
        <pane location="" divider="1" orientation="1" />
    </panes>
    <views>
        <view id="1" visible="false" inframe="false" stylebar="true" location="3,3" size="277" window="100,100,600,400" />
        <view id="4" toolbar="0 || 2020 , 2021 , 2022 || 2001 , 2003 , 2002 , 2004 , 2005 || 2040 , 2041 , 2042 , 2044 , 2043" visible="false" inframe="false" stylebar="false" location="1,1" size="300" window="100,100,600,400" />
        <view id="8" toolbar="1001 | 1002 | 1003  || 1005 | 1004 || 1006 | 1007 | 1010 || 1008 | 1009 || 6" visible="false" inframe="false" stylebar="false" location="1,3" size="300" window="100,100,600,400" />
        <view id="2" visible="false" inframe="false" stylebar="true" location="3" size="380" tab="ALGEBRA" window="100,100,600,400" />
        <view id="16" visible="false" inframe="false" stylebar="false" location="1" size="300" window="50,50,500,500" />
        <view id="32" visible="false" inframe="false" stylebar="true" location="1" size="300" window="50,50,500,500" />
        <view id="64" toolbar="0" visible="false" inframe="false" stylebar="false" location="1" size="480" window="50,50,500,500" />
        <view id="128" visible="false" inframe="false" stylebar="false" location="1" size="480" window="50,50,500,500" />
        <view id="4097" visible="false" inframe="false" stylebar="true" location="1" size="237" window="100,100,700,550" />
        <view id="70" toolbar="0 || 2020 || 2021 || 2022" visible="false" inframe="false" stylebar="true" location="1" size="900" window="50,50,500,500" />
        <view id="512" toolbar="0 | 1 501 5 19 , 67 | 2 15 45 18 , 7 37 | 514 3 9 , 13 44 , 47 | 16 51 | 551 550 11 ,  20 22 21 23 , 55 56 57 , 12 | 69 | 510 511 , 512 513 | 533 531 , 534 532 , 522 523 , 537 536 , 535 , 538 | 521 520 | 36 , 38 49 560 | 571 30 29 570 31 33 | 17 | 540 40 41 42 , 27 28 35 , 6 , 502" visible="true" inframe="false" stylebar="false" location="3" size="1029" window="100,100,600,400" />
    </views>
    <toolbar show="true" items="0 73 62 | 1 501 67 , 5 19 , 72 75 76 | 2 15 45 , 18 65 , 7 37 | 4 3 8 9 , 13 44 , 58 , 47 | 16 51 64 , 70 | 10 34 53 11 , 24  20 22 , 21 23 | 55 56 57 , 12 | 36 46 , 38 49  50 , 71  14  68 | 30 29 54 32 31 33 | 25 17 26 60 52 61 | 40 41 42 , 27 28 35 , 6" position="1" help="false" />
    <input show="true" cmd="true" top="algebra" />
    <dockBar show="false" east="false" />
</perspective>
    </perspectives>
    <labelingStyle  val="0"/>
    <font  size="16"/>
</gui>
<euclidianView>
    <viewNumber viewNo="1"/>
    <size  width="277" height="588"/>
    <coordSystem xZero="320.50000000000017" yZero="183.5" scale="50.00000000000002" yscale="50"/>
    <evSettings axes="true" grid="true" gridIsBold="false" pointCapturing="3" rightAngleStyle="1" checkboxSize="26" gridType="3"/>
    <bgColor r="255" g="255" b="255"/>
    <axesColor r="37" g="37" b="37"/>
    <gridColor r="192" g="192" b="192"/>
    <lineStyle axes="1" grid="0"/>
    <axis id="0" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
    <axis id="1" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
</euclidianView>
<algebraView>
    <mode val="1"/>
    <collapsed val="0"/>
</algebraView>
<kernel>
    <uses3D val="true"/>
    <continuous val="false"/>
    <usePathAndRegionParameters val="true"/>
    <decimals val="2"/>
    <angleUnit val="degree"/>
    <algebraStyle val="2" spreadsheet="0"/>
    <coordStyle val="0"/>
</kernel>
<tableview min="0" max="0" step="0"/>
<scripting blocked="false" disabled="false"/>
<euclidianView3D>
    <coordSystem xZero="-0.6504528252066868" yZero="-0.33047043474869997" zZero="-2.4777010833587454" scale="60.67107623140951" xAngle="20" zAngle="-60"/>
    <evSettings axes="true" grid="false" gridIsBold="false" pointCapturing="3" rightAngleStyle="1" gridType="3"/>
    <axis id="0" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
    <axis id="1" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
    <axis id="2" show="true" label="" unitLabel="" tickStyle="1" showNumbers="true"/>
    <plate show="true"/>
    <bgColor r="255" g="255" b="255"/>
    <clipping use="false" show="false" size="1"/>
    <projection type="0"/>
</euclidianView3D>
<construction title="" author="" date="">

<!--==============================================================================-->
<!--=============================   END-of-HEADER   ==============================-->
<!--==============================================================================-->

geogebra.xml__02_GEOMETRY_POINT:

<!--==============================================================================-->
<!--============================   START-of-POINTS   =============================-->
<!--==============================================================================-->

<expression label="MYPOINT" exp="(2, 1, 3)" type="point"/>
<element type="point3d" label="MYPOINT">
    <show object="true" label="true" ev="4"/>
    <objColor r="255" g="0" b="0" alpha="0"/>
    <layer val="0"/>
    <labelMode val="0"/>
    <animation step="0.1" speed="1" type="1" playing="false"/>
    <pointSize val="5"/>
    <coords x="2" y="1" z="3" w="1"/>
</element>

<expression label="OTPOINT" exp="(-1, -1, 2)" type="point"/>
<element type="point3d" label="OTPOINT">
    <show object="true" label="true" ev="4"/>
    <objColor r="0" g="255" b="0" alpha="0"/>
    <layer val="0"/>
    <labelMode val="0"/>
    <animation step="0.1" speed="1" type="1" playing="false"/>
    <pointSize val="5"/>
    <coords x="-1" y="-1" z="2" w="1"/>
</element>

<expression label="EXPOINT" exp="(1, 1, 6)" type="point"/>
<element type="point3d" label="EXPOINT">
    <show object="true" label="true" ev="4"/>
    <objColor r="0" g="0" b="255" alpha="0"/>
    <layer val="0"/>
    <labelMode val="0"/>
    <animation step="0.1" speed="1" type="1" playing="false"/>
    <pointSize val="5"/>
    <coords x="1" y="1" z="6" w="1"/>
</element>

<!--==============================================================================-->
<!--=============================   END-of-POINTS   ==============================-->
<!--==============================================================================-->

geogebra.xml__03_GEOMETRY_SEGMENT:

<!--==============================================================================-->
<!--===========================   START-of-SEGMENTS  =============================-->
<!--==============================================================================-->

<command name="Segment">
    <input a0="MYPOINT" a1="OTPOINT"/>
    <output a0="MYLINE"/>
</command>
<element type="segment3d" label="MYLINE">
    <show object="true" label="false" ev="4"/>
    <objColor r="255" g="0" b="0" alpha="0"/>
    <layer val="0"/>
    <labelMode val="0"/>
    <lineStyle thickness="1" type="0" typeHidden="1"/>
    <outlyingIntersections val="false"/>
    <keepTypeOnTransform val="true"/>
</element>

<command name="Segment">
    <input a0="MYPOINT" a1="EXPOINT"/>
    <output a0="OTLINE"/>
</command>
<element type="segment3d" label="OTLINE">
    <show object="true" label="false" ev="4"/>
    <objColor r="0" g="255" b="0" alpha="0"/>
    <layer val="0"/>
    <labelMode val="0"/>
    <lineStyle thickness="1" type="0" typeHidden="1"/>
    <outlyingIntersections val="false"/>
    <keepTypeOnTransform val="true"/>
</element>

<command name="Segment">
    <input a0="OTPOINT" a1="EXPOINT"/>
    <output a0="EXLINE"/>
</command>
<element type="segment3d" label="EXLINE">
    <show object="true" label="false" ev="4"/>
    <objColor r="0" g="0" b="255" alpha="0"/>
    <layer val="0"/>
    <labelMode val="0"/>
    <lineStyle thickness="1" type="0" typeHidden="1"/>
    <outlyingIntersections val="false"/>
    <keepTypeOnTransform val="true"/>
</element>

<!--==============================================================================-->
<!--============================   END-of-SEGMENTS  ==============================-->
<!--==============================================================================-->

geogebra.xml__04_GEOMETRY_FACE:

<!--==============================================================================-->
<!--=============================   START-of-FACE   ==============================-->
<!--==============================================================================-->

<command name="Polygon">
    <input a0="MYPOINT" a1="OTPOINT" a2="EXPOINT"/>
    <output a0="MYFACE" a1="expoint" a2="mypoint" a3="otpoint"/>
</command>
<element type="polygon3d" label="MYFACE">
    <lineStyle thickness="0" type="0" typeHidden="0" opacity="114"/>
    <show object="true" label="true" ev="4"/>
    <objColor r="255" g="255" b="102" alpha="0.1"/>
    <layer val="0"/>
    <labelMode val="0"/>
</element>
<element type="segment3d" label="expoint">
    <show object="false" label="false" ev="4"/>
    <objColor r="192" g="192" b="192" alpha="0"/>
    <layer val="0"/>
    <labelMode val="0"/>
    <auxiliary val="false"/>
    <lineStyle thickness="0" type="0" typeHidden="0"/>
    <outlyingIntersections val="false"/>
    <keepTypeOnTransform val="true"/>
</element>
<element type="segment3d" label="mypoint">
    <show object="false" label="false" ev="4"/>
    <objColor r="192" g="192" b="192" alpha="0"/>
    <layer val="0"/>
    <labelMode val="0"/>
    <auxiliary val="false"/>
    <lineStyle thickness="0" type="0" typeHidden="0"/>
    <outlyingIntersections val="false"/>
    <keepTypeOnTransform val="true"/>
</element>
<element type="segment3d" label="otpoint">
    <show object="false" label="false" ev="4"/>
    <objColor r="192" g="192" b="192" alpha="0"/>
    <layer val="0"/>
    <labelMode val="0"/>
    <auxiliary val="false"/>
    <lineStyle thickness="0" type="0" typeHidden="0"/>
    <outlyingIntersections val="false"/>
    <keepTypeOnTransform val="true"/>
</element>

<!--==============================================================================-->
<!--==============================   END-of-FACE   ===============================-->
<!--==============================================================================-->

geogebra.xml__05_TRAILER:

<!--==============================================================================-->
<!--============================   START-of-TRAILER   ============================-->
<!--==============================================================================-->

</construction>
</geogebra>