1

I have some .Net 3.5 code that uses the XDocument class.

Can you suggest a quick and dirty way to get this code running in .Net 2.0?

    public static HaarClassifierCascade Parse(XDocument xDoc)
    {
        HaarClassifierCascade cascade = null;
        XElement stages_fn;
        XElement seq_fn = null; /* sequence */
        XElement fn;
        int n;
        int i = 0, j = 0, k = 0, l = 0;
        int parent, next;

        stages_fn = xDoc.Descendants(stageId).First();

        n = stages_fn.Elements().Count();
        cascade = new HaarClassifierCascade(n);

        seq_fn = xDoc.Descendants(sizeId).First();
        string[] size = seq_fn.Value.Split(' ');
        int.TryParse(size[0], out cascade.OriginalWindowSize.Width);
        int.TryParse(size[1], out cascade.OriginalWindowSize.Height);

        XElement stage_fn = (XElement)stages_fn.FirstNode;
        while (null != stage_fn)
        {
            XElement trees_fn = stage_fn.Element(treeId);

            n = trees_fn.Elements().Count();
            cascade.StageClassifiers[i].Classifiers = new List<HaarClassifier>(n);
            for (j = 0; j < n; j++)
            {
                cascade.StageClassifiers[i].Classifiers.Add(new HaarClassifier());
                cascade.StageClassifiers[i].Classifiers[j].HaarFeatures = null;
            }

            cascade.StageClassifiers[i].Count = n;

            j = 0;
            XElement tree_fn = (XElement)trees_fn.FirstNode;
            while (null != tree_fn)
            {
                HaarClassifier classifier;
                int lastIndex;

                classifier = cascade.StageClassifiers[i].Classifiers[j];
                classifier.Count = tree_fn.Elements().Count();

                classifier.HaarFeatures = new List<HaarFeature>(classifier.Count);
                for (k = 0; k < classifier.Count; k++)
                {
                    classifier.HaarFeatures.Add(new HaarFeature());
                    classifier.Left.Add(0);
                    classifier.Right.Add(0);
                    classifier.Threshold.Add(0);
                    classifier.Alpha.Add(0);
                }
                classifier.Alpha.Add(0);

                lastIndex = 0;
                k = 0;
                XNode node_fn = tree_fn.FirstNode;
                while (null != node_fn)
                {
                    if (!(node_fn is XElement))
                        goto next_node_fn;

                    XElement feature_fn;
                    XElement rects_fn;

                    feature_fn = ((XElement)node_fn).Element(featureId);
                    rects_fn = feature_fn.Element(rectsId);

                    l = 0;
                    XNode rect_fn = rects_fn.FirstNode;
                    while (null != rect_fn)
                    {
                        if (!(rect_fn is XElement))
                            goto next_rect_fn;

                        {
                            string[] rectangleParams = ((XElement)rect_fn).Value.Split(' ');
                            Rectangle rectangle = new Rectangle();
                            rectangle.X = int.Parse(rectangleParams[0]);
                            rectangle.Y = int.Parse(rectangleParams[1]);
                            rectangle.Width = int.Parse(rectangleParams[2]);
                            rectangle.Height = int.Parse(rectangleParams[3]);

                            classifier.HaarFeatures[k].Rectangles[l] = new HaarRectangle();
                            classifier.HaarFeatures[k].Rectangles[l].Weight = float.Parse(rectangleParams[4]);
                            classifier.HaarFeatures[k].Rectangles[l].Rectangle = rectangle;
                        }

                        l++;
                    next_rect_fn:
                        rect_fn = (XElement)rect_fn.NextNode;
                    }

                    for (; l < 3; ++l)
                        classifier.HaarFeatures[k].Rectangles[l] = new HaarRectangle();

                    fn = feature_fn.Element(tiltedId);
                    int.TryParse(fn.Value, out classifier.HaarFeatures[k].Tilted);

                    fn = ((XElement)node_fn).Element(thresholdId);
                    classifier.Threshold[k] = float.Parse(fn.Value);

                    fn = ((XElement)node_fn).Element(left_nodeId);
                    if (null != fn) /* left node */
                        classifier.Left[k] = int.Parse(fn.Value);
                    else
                    {
                        fn = ((XElement)node_fn).Element(left_valId);

                        classifier.Left[k] = -lastIndex;
                        classifier.Alpha[lastIndex++] = float.Parse(fn.Value);
                    }

                    fn = ((XElement)node_fn).Element(right_nodeId);
                    if (null != fn) /* right node */
                        classifier.Right[k] = int.Parse(fn.Value);
                    else
                    {
                        fn = ((XElement)node_fn).Element(right_valId);

                        classifier.Right[k] = -lastIndex;
                        classifier.Alpha[lastIndex++] = float.Parse(fn.Value);
                    }

                    k++;
                next_node_fn:
                    node_fn = (XElement)node_fn.NextNode;
                }

                j++;
                tree_fn = (XElement)tree_fn.NextNode;
            }

            fn = stage_fn.Element(stageThresholdId);
            cascade.StageClassifiers[i].Threshold = float.Parse(fn.Value);

            parent = i - 1;
            next = -1;

            fn = stage_fn.Element(parentId);
            parent = int.Parse(fn.Value);

            fn = stage_fn.Element(nextId);
            next = int.Parse(fn.Value);

            cascade.StageClassifiers[i].Parent = parent;
            cascade.StageClassifiers[i].Next = next;
            cascade.StageClassifiers[i].Child = -1;

            if (parent != -1 && cascade.StageClassifiers[parent].Child == -1)
                cascade.StageClassifiers[parent].Child = i;

            i++;
            stage_fn = (XElement)stage_fn.NextNode;
        }

        return cascade;
    }
Biff MaGriff
  • 8,102
  • 9
  • 61
  • 98
  • Why are you constrained to .Net 2? – svick May 06 '11 at 17:37
  • Upgrades to existing system, user's can't get higher .net version installed due to potential conflicts with vendor apps, help desk does not want to roll out any potential hotfixes, the list goes on. – Biff MaGriff May 06 '11 at 17:49
  • @Bill, I understand there's probably not much you can do about it, but I think you should try. .Net libraries are intentionally versioned, so that you can have more than one version at any given time, without any problems. – svick May 06 '11 at 18:12
  • @Bill, also, re: “help desk does not want to roll out any potential hotfixes”. Eh? It seems like they are not installing hotfixes right now, so they are potentially very unsecure. Installing .Net 3.5 won't make them any less secure. If they don't want to install any new, untested technologies, I would understand that. But .Net 3.5 is out since 2007! – svick May 06 '11 at 18:15
  • 2
    @svick Politics takes precedence over design, it's my job to make it work. – Biff MaGriff May 06 '11 at 20:21

2 Answers2

3

You could try to compile the mono sources in your .Net 2.0 project: https://github.com/mono

Here are the sources for mono's implementation of System.Xml.Linq:

https://github.com/mono/mono/tree/c7c906d69ac9e360ce3e7d517258b8eea2b962b2/mcs/class/System.Xml.Linq

This ought to be feasible in theory since .Net 3 shares the same runtime with .Net 2. However I doubt this will be quick...

jeroenh
  • 26,362
  • 10
  • 73
  • 104
1

XDocument and XElement run on top of LINQ (Language INtegrated Query). Therefor the code itself cannot run within the .NET 2.0 context.

You could however try using Xml Serialization or XmlReader.

Chad Moran
  • 12,834
  • 2
  • 50
  • 72
  • That's not quite accurate. XDocument and XElement both _support_ LINQ, they don't "run on top of it". Note that the code that the OP posted does not use LINQ query comprehensions or any of the LINQ extension methods. – John Saunders May 06 '11 at 00:26