Search code examples
c#xmlopenxml

Comparing Two XML Elements In OpenXML


I'm new to XML and C# so I'm having a little trouble implementing the following. Hopefully someone can point me in the right direction. So I'm developing in C# with OpenXML 2.5 and I'm trying to check, after I create a Font, if that Font already exists in the Font collection. If it already does then I want to return the index of the Font.

I am stuck on writing an efficient method to compare these Font objects and I believe that comparing their respective XML code is the way to go. I believe that these Font objects are wrappers for XML code. So I thought that I should be able to compare two XML elements and figure out if the Font already exists or not.

Does this make any sense? Here is an example, because I fear that I'm being overly complicated in my explanation.

1. Basically, I want to find if this:

  <x:font>
    <x:b />
    <x:sz val="18" />
    <x:color theme="3" />
    <x:name val="Cambria" />
    <x:family val="2" />
    <x:scheme val="major" />
  </x:font>

2. Already exists in here:

<x:fonts count="18" x14ac:knownFonts="1" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  <x:font>
    <x:sz val="11" />
    <x:color theme="1" />
    <x:name val="Calibri" />
    <x:family val="2" />
    <x:scheme val="minor" />
  </x:font>
  <x:font>
    <x:sz val="11" />
    <x:color theme="1" />
    <x:name val="Calibri" />
    <x:family val="2" />
    <x:scheme val="minor" />
  </x:font>
  <x:font>
    <x:b />
    <x:sz val="18" />
    <x:color theme="3" />
    <x:name val="Cambria" />
    <x:family val="2" />
    <x:scheme val="major" />
  </x:font>
  <x:font>
    <x:b />
    <x:sz val="15" />
    <x:color theme="3" />
    <x:name val="Calibri" />
    <x:family val="2" />
    <x:scheme val="minor" />
  </x:font>
</x:fonts>

3. And the method returns the index of the Font. So in this example my function would return 2.

Any help with this would be greatly appreciated!

thanks, Justin


Solution

  • Appreciate the help, but figured out an easier way of doing it actually from within the sdk. Turns out there is a method called OuterXml for each OpenXml Object.

    According to the Microsoft definition: OuterXml: Gets the markup that represents the current element and all of its child elements.

    It is much better than InnerXml: Gets or sets the markup that represents only the child elements of the current element.

    So I can simply do:

    private Stylesheet _stylesheet = _workbookPart.WorkbookStylesPart.Stylesheet;
    
    public int GetFontIndex(Font font)
    {
         int index = 0;
         foreach (var existingFont in _stylesheet.Descendants<Font>())
         {
             if (font.OuterXml.Equals(existingFont.OuterXml)) return index;
             index++;
         }
    
         return -1;
     }