April 07, 2008

Extracting XML data from drawings using a new .NET API in AutoCAD 2009

This post is the latest in the series of closer looks at the new APIs in AutoCAD 2009. It covers the Data Extraction API, a new .NET API allowing you to drive the Data Extraction feature inside AutoCAD.

There is a very thorough C# sample included on the ObjectARX SDK (under samples/dotNet/DataExtraction), so I thought I'd focus on a much simpler example where we extract data from a single drawing.

Here's the C# code:

using System.Collections.Generic;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.DataExtraction;

namespace DataExtraction

{

publicclassCommands

{

conststring path =

@"c:\Program Files\Autodesk\AutoCAD 2009\Sample\";

conststring fileName =

"Visualization - Aerial.dwg";

conststring outputXmlFile =

@"c:\temp\data-extract.xml";

[CommandMethod("extd")]

publicvoid extractData()

{

if (!System.IO.File.Exists(path + fileName))

{

Document doc =

Application.DocumentManager.MdiActiveDocument;

Editor ed =

doc.Editor;

ed.WriteMessage("\nFile does not exist.");

return;

}

// Create some settings for the extraction

IDxExtractionSettings es =

newDxExtractionSettings();

IDxDrawingDataExtractor de =

es.DrawingDataExtractor;

de.Settings.ExtractFlags =

ExtractFlags.ModelSpaceOnly |

ExtractFlags.XrefDependent |

ExtractFlags.Nested;

// Add a single file to the settings

IDxFileReference fr =

newDxFileReference(path, path + fileName);

de.Settings.DrawingList.AddFile(fr);

// Scan the drawing for object types & their properties

de.DiscoverTypesAndProperties(path);

List<IDxTypeDescriptor> types =

de.DiscoveredTypesAndProperties;

// Select all the types and properties for extraction

// by adding them one-by-one to these two lists

List<string> selTypes = newList<string>();

List<string> selProps = newList<string>();

foreach (IDxTypeDescriptor type in types)

{

selTypes.Add(type.GlobalName);

foreach (

IDxPropertyDescriptor pr in type.Properties

)

{

if (!selProps.Contains(pr.GlobalName))

selProps.Add(pr.GlobalName);

}

}

// Pass this information to the extractor

de.Settings.SetSelectedTypesAndProperties(

types,

selTypes,

selProps

);

// Now perform the extraction itself

de.ExtractData(path);

// Get the results of the extraction

System.Data.DataTable dataTable =

de.ExtractedData;

// Output the extracted data to an XML file

if (dataTable.Rows.Count > 0)

{

dataTable.TableName = "My_Data_Extract";

dataTable.WriteXml(outputXmlFile);

}

}

}

}

Here are the first few objects from the output file found in c:\temp\data-extract.xml after running the EXTD command: