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

{

  public class Commands

  {

    const string path =

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

    const string fileName =

      "Visualization - Aerial.dwg";

    const string outputXmlFile =

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

    [CommandMethod("extd")]

    public void 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 =

        new DxExtractionSettings();

      IDxDrawingDataExtractor de =

        es.DrawingDataExtractor;

      de.Settings.ExtractFlags =

        ExtractFlags.ModelSpaceOnly |

        ExtractFlags.XrefDependent |

        ExtractFlags.Nested;

      // Add a single file to the settings

      IDxFileReference fr =

        new DxFileReference(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 = new List<string>();

      List<string> selProps = new List<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:

<?xml version="1.0" standalone="yes"?>

<DocumentElement>

  <My_Data_Extract>

    <AcDxHandleData>183</AcDxHandleData>

    <Layer>0</Layer>

    <LinetypeScale>1</LinetypeScale>

    <PlotStyleName>ByLayer</PlotStyleName>

    <LineWeight>ByLayer</LineWeight>

    <Material>Material 3</Material>

    <Linetype>ByLayer</Linetype>

    <Color>ByLayer</Color>

    <AcDxObjectTypeName>3D Solid</AcDxObjectTypeName>

    <AcDxObjectTypeGlobalName>

      Autodesk.AutoCAD.DatabaseServices.Solid3d

    </AcDxObjectTypeGlobalName>

    <AcDxDwgSummaryDwgName>

      Visualization - Aerial.dwg

    </AcDxDwgSummaryDwgName>

    <AcDxDwgSummaryDwgLocation>

      c:\Program Files\Autodesk\AutoCAD 2009\Sample

    </AcDxDwgSummaryDwgLocation>

    <AcDxDwgSummaryDwgSize>472480</AcDxDwgSummaryDwgSize>

    <AcDxDwgSummaryDwgCreated>

      2007-01-03T00:44:20+01:00

    </AcDxDwgSummaryDwgCreated>

    <AcDxDwgSummaryDwgModified>

      2007-01-03T00:44:20+01:00

    </AcDxDwgSummaryDwgModified>

    <AcDxDwgSummaryDwgAccessed>

      2008-03-03T11:40:53.796875+01:00

    </AcDxDwgSummaryDwgAccessed>

    <AcDxDwgSummaryDwgTitle />

    <AcDxDwgSummaryDwgSubject />

    <AcDxDwgSummaryDwgAuthor />

    <AcDxDwgSummaryDwgKeywords />

    <AcDxDwgSummaryDwgComments />

    <AcDxDwgSummaryDwgHyperLinkBase />

    <AcDxDwgSummaryDwgLastSavedBy>

      thompsl

    </AcDxDwgSummaryDwgLastSavedBy>

    <AcDxDwgSummaryDwgRevisionNumber />

    <AcDxDwgSummaryDwgTotalEditingTime>

      1179

    </AcDxDwgSummaryDwgTotalEditingTime>

    <AcDxEntityHyperlink />

  </My_Data_Extract>

  <My_Data_Extract>

    <AcDxHandleData>191</AcDxHandleData>

    <Layer>0</Layer>

    <LinetypeScale>1</LinetypeScale>

    <PlotStyleName>ByLayer</PlotStyleName>

    <LineWeight>ByLayer</LineWeight>

    <Material>Material 3</Material>

    <Linetype>ByLayer</Linetype>

    <Color>ByLayer</Color>

    <AcDxObjectTypeName>3D Solid</AcDxObjectTypeName>

    <AcDxObjectTypeGlobalName>

      Autodesk.AutoCAD.DatabaseServices.Solid3d

    </AcDxObjectTypeGlobalName>

    <AcDxDwgSummaryDwgName>

      Visualization - Aerial.dwg

    </AcDxDwgSummaryDwgName>

    <AcDxDwgSummaryDwgLocation>

      c:\Program Files\Autodesk\AutoCAD 2009\Sample

    </AcDxDwgSummaryDwgLocation>

    <AcDxDwgSummaryDwgSize>472480</AcDxDwgSummaryDwgSize>

    <AcDxDwgSummaryDwgCreated>

      2007-01-03T00:44:20+01:00

    </AcDxDwgSummaryDwgCreated>

    <AcDxDwgSummaryDwgModified>

      2007-01-03T00:44:20+01:00

    </AcDxDwgSummaryDwgModified>

    <AcDxDwgSummaryDwgAccessed>

      2008-03-03T11:40:53.796875+01:00

    </AcDxDwgSummaryDwgAccessed>

    <AcDxDwgSummaryDwgTitle />

    <AcDxDwgSummaryDwgSubject />

    <AcDxDwgSummaryDwgAuthor />

    <AcDxDwgSummaryDwgKeywords />

    <AcDxDwgSummaryDwgComments />

    <AcDxDwgSummaryDwgHyperLinkBase />

    <AcDxDwgSummaryDwgLastSavedBy>

      thompsl

    </AcDxDwgSummaryDwgLastSavedBy>

    <AcDxDwgSummaryDwgRevisionNumber />

    <AcDxDwgSummaryDwgTotalEditingTime>

      1179

    </AcDxDwgSummaryDwgTotalEditingTime>

    <AcDxEntityHyperlink />

  </My_Data_Extract>

  <!-- Stuff deleted from the XML output -->

  <!-- ... -->

</DocumentElement>

One response to “Extracting XML data from drawings using a new .NET API in AutoCAD 2009”

  1. Fernando Malard Avatar
    Fernando Malard

    Kean,
    Is this available through C++?
    How to make our custom objects support XML exporting?

    Fernando.

  2. Kean Walmsley Avatar

    Fernando,

    I don't think that's currently possible: it doesn't appear to pick up properties exposed through COM, although I haven't tried with a managed wrapper.

    Please submit your question via the ADN site for someone to look into.

    Regards,

    Kean

  3. Kean Walmsley Avatar

    Oh - and this is a managed API, so it can be called from C++. There isn't an unmanaged C++ API, though.

    Kean

  4. When compiling, I get the following message: The type or namespace name 'DataExtraction' does not exist in the namespace 'Autodesk.AutoCAD' (are you missing an assembly reference?)

    Which assembly do I need to add as a reference?

  5. Kean Walmsley Avatar

    Ah yes - I missed a step: you need to add a project reference to AcDx.dll, which can be found in the inc-win32 and inc-x64 folders of the ObjectARX 2009 SDK (as well as being in the AutoCAD 2009 root folder).

    Regards,

    Kean

  6. Hello,

    Was the following an error:
    IDxExtractionSettings es =
    es = new DxExtractionSettings();

    Should it have been written like:
    IDxExtractionSettings es = new DxExtractionSettings();

    Or, doesn't it make any difference?

    Thank You

  7. Hi Tom,

    It was a typo - thanks for spotting it. I've fixed the post.

    Regards,

    Kean

  8. you can filter the properties customized and bring only what you need?

  9. Kean Walmsley Avatar

    I believe so, although I didn't try it.

    Kean

    1. Kean,

      I've been looking into this because I only need specific properties. I cant seem to be able to figure out a way to do this. Do you have any insight on how this can be done?

      1. Kean Walmsley Avatar

        Frank,

        You should be able to add a subset of the properties to the list - based on your criteria - and then use that to generate the report.

        Although I haven't actually done this myself.

        Kean

  10. Hi Kean.
    I just popped this into VB and took out the hard coded filenames. I ran it on a drawing created by my automation program, and the only thing I don't see extracted is Xdata.
    I'd be interested in figuring out if that could be done. (in the data extraction tool, I know how to do it otherwise)

    Actually I also saw something else a little strange... I have a particular type of block which is inserted with varying X-scales so that the length of the block changes. The Attribute references show up under the data for the block, but the specific data for the attribute references themselves does not show up next in the list, like it did for other uniformly scaled blocks. At the moment I don't think this concerns me, I just found it interesting.

  11. Hi David,

    I hadn't tried this with Xdata, but it doesn't fully surprise me that this isn't currently supported.

    Xdata content tends to be stored fairly generically - the group codes don't have standardised, human-readable labels - so some logic would be needed to map these to XML elements. Not to say it's very hard to do, but it doesn't surprise me that it hasn't been done.

    I hadn't come across non-uniform blocks acting differently. If you're an ADN member it would be great if you could submit it there with a reproducible case.

    Thanks,

    Kean

  12. Mike Robertson Avatar
    Mike Robertson

    Where can I find a list of the valid ExtractFlags values?

    Thanks,
    Mike

  13. Kean Walmsley Avatar

    Hi Mike,

    If you right-click ExtractFlags in Visual Studio and select "Go To Definition", then you'll see the values:

    public enum ExtractFlags
    {
    None = 0,
    Nested = 1,
    Xref = 2,
    XrefDependent = 4,
    ModelSpaceOnly = 8,
    ExtractBlockOnly = 16,
    }

    Regards,

    Kean

  14. Kean,

    Is the DataExtraction C# example no longer included in the ObjectARX SDK?

  15. Ted,

    So it would seem (I have SDKs back to 2010 on this system and don't see it there). I suggest pinging the ADN team, to see if they're posted somewhere they can point you at (whether or not you're an ADN member - these should be made publicly available).

    Just drop me an email if you have trouble getting a response.

    Regards,

    Kean

  16. Hi Kean,

    Not having much luck with getting a response. I'm not an ADN Member so I'm not sure who to contact. Any help appreciated.

    -Ted

  17. I am trying the code in this example and I'm getting the error:
    ''Could not load file or assembly 'AcDx, Version=20.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.'
    I was wondering if there's a way to make it work as a standalone console app.

    1. No, it's dependent on AutoCAD.

      Kean

      1. Hi Kean,

        I ran into the same error while trying out the example. A quick research tells me (including the above comment) that I should have theAutoCAD instance running, or alternately make use of accoreconsole.exe (as seen from another one of your posts). Could you please guide me on where to find the exact steps as I'm very new to C# or .NET in general.

        TIA.

        -Sailesh

        1. Kean Walmsley Avatar

          Sorry - I suggest posting to the AutoCAD .NET forum for help on this (I'm no longer involved in this area myself).

          Kean

          1. Thanks, I'll do that.

            1. hi sailesh. If you found something, can you please refer me to that since i am also new to c# and facing same issues

  18. This is a great article for anyone who wants to learn about extracting XML data from drawings using a new .NET API in AutoCAD

Leave a Reply to Noam Wertheim Cancel reply

Your email address will not be published. Required fields are marked *