# 2.5: Data Export from Karamba3D

When it comes to exporting data from a Karamba3D model to another data-format one could simply go through the object tree of the model and iterate manually over the existing entities like e.g. nodes, elements, materials, . . . . The use of a builder pattern removes some of the bureaucratic overhead involved in this approach. The script in the example “**ModelExport.gh**” shows how to generate an XML-file based on a given Karamba3D-model. The output consists of a string which can be streamed to a file. When opened with a web-browser a nicely formatted tree results (see fig. 2.5.1).

![Fig. 2.5.1: ModelExport.gh](/files/-MXH_8mQ8Ka3_HUVaTMk)

By inheriting from **"Karamba.Exporters.ExportBuilder"** and overriding **"builder"**-methods a builder-class can be configured to export Karamba3D-models to any format - here XML.

The corresponding source-code looks like this:

```csharp
...
using System.Xml;
using System.IO;
using Karamba.Models;
using Karamba.Nodes;
using Karamba.CrossSections;
using Karamba.Elements;
using Karamba.Loads;
using Karamba.Materials;
using Karamba.Supports;
using Karamba.Geometry;
...
private void RunScript(object Model_in, ref object XML)
{
    var model = Model_in as Model;
    if (model == null) {
      throw new ArgumentException("The input is not of type model!");
    }

    var builder = new BuilderXML();
    var director = new Karamba.Exporters.ExportDirector();
    director.ConstructExport(model, builder);

    XML = builder.getProduct();
}

// <Custom additional code>
public class BuilderXML : Karamba.Exporters.ExportBuilder {
  // the XML document
  private XmlDocument doc_ = new XmlDocument();
  // the model inside the xml-document
  private XmlElement model_;

  public override void newProduct() {
    model_ = (XmlElement) doc_.AppendChild(doc_.CreateElement("K3DModel"));
  }

  public override void buildMaterial(FemMaterial m, int ind) {
    var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("FemMaterial"));
    xml_node.InnerText = "ind: " + ind + ":" + m.ToString();
  }

  public override void buildVertex(Node v) {
    var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("Node"));
    xml_node.InnerText = v.ToString();
  }

  public override void buildCroSec(CroSec crosec) {
    var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("CroSec"));
    xml_node.InnerText = crosec.ToString();
  }

  public override void buildElement(ModelElement e, Model model) {
    var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("ModelElement"));
    xml_node.InnerText = e.ToString();
  }

  public override void buildElementLoad(ModelElement elem, Model model) {
    foreach (var l in elem.Elem_loads) {
      var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("ElementLoad"));
      xml_node.InnerText = l.ToString();
    }
  }

  public override void buildLoadCase(int lc_ind, Model model) {
    Vector3 g_vec = new Vector3(0, 0, 0);
    foreach (GravityLoad g in model.gravities.Values)
    {
      if (model.lcActivation.FebLoadCaseInds(g.LcName).Contains(lc_ind))
      {
        g_vec = g.force;
      }
    }

    var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("LoadCase"));
    xml_node.InnerText = "load-case: " + lc_ind + " g =" + g_vec;
  }

  public override void buildSupport(Support s) {
    var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("Support"));
    xml_node.InnerText = s.ToString();
  }

  public override void buildPointLoad(PointLoad p) {
    var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("PointLoad"));
    xml_node.InnerText = p.ToString();
  }

  public override void buildMeshLoad(MeshLoad m) {
    var xml_node = (XmlElement) model_.AppendChild(doc_.CreateElement("MeshLoad"));
    xml_node.InnerText = m.ToString();
  }

  public string getProduct() {
    StringWriter sw = new StringWriter();
    XmlTextWriter tx = new XmlTextWriter(sw);
    doc_.WriteTo(tx);
    string str = sw.ToString();//
    return str;
  }
}
// </Custom additional code>
```

The first part of the script comprises the “RunScript”-method. There the “Model\_in”-object gets converted to a Karamba3D-Model. In line 20 follows the creation of a builder-object which does the conversion-work. The class “BuilderXML” gets defined further below in the script. A director-object is instantiated in the next line. Its task consists of iterating over the model constituents and presenting them to the builder. Calling “ConstructExport” in line 22 initiates the creation process. Line 24 assigns the builder’s product to the output variable “XML”.

The “BuilderXML”-class derives from Karamba.Exporters.ExportBuilder and overrides some of its methods. In order to keep things simple each build-method adds a XML-node which contains the string-representation of the corresponding argument. In case of “ModelElement” the corresponding build-method does not know which type of element gets passed. Thus one has to apply pattern matching to find get the right type (e.g. “ModelBeam”, “ModelTruss”, “ModelShell” or “ModelSpring”)

{% file src="/files/vVjS7psEKU9l6EGkFojV" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://scripting.karamba3d.com/2.-scripting-with-karamba3d-inside-grasshopper/2.5-data-export-from-karamba3d.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
