比较 OpenXML 中的两个 XML 元素

问题描述 投票:0回答:3

我是 XML 和 C# 新手,因此在实现以下内容时遇到了一些困难。希望有人能指出我正确的方向。因此,我正在使用 OpenXML 2.5 在 C# 中进行开发,并且在创建字体后尝试检查该字体是否已存在于字体集合中。如果它已经存在,那么我想返回字体的索引。

我一直致力于编写一种有效的方法来比较这些 Font 对象,并且我相信比较它们各自的 XML 代码是正确的方法。我相信这些 Font 对象是 XML 代码的包装器。所以我认为我应该能够比较两个 XML 元素并确定字体是否已经存在。

这有什么意义吗?这是一个例子,因为我担心我的解释过于复杂。

1. 基本上,我想知道是否是这样:

  <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. 已经存在于此处:

<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. 该方法返回 Font 的索引。所以在这个例子中我的函数将返回

2

如有任何帮助,我们将不胜感激!

谢谢, 贾斯汀

c# xml openxml
3个回答
1
投票

查看用于查询 XMLDocuments 的 XPath,然后您可以通过 XPath 查询在 XMLDocument 上使用 FindNode()。

但是,它不会返回索引号。除非另有指示,否则 XML 节点不会排序,因此说“这是第三个”的想法不会完成,因为下次您查看时它可能是第五个! (可能不是,但是类似的行为符合 XML 规范)。不过,您可以做的是获取实际的节点 (),从中您可以获取包含它的父节点 ()。


1
投票

感谢您的帮助,但实际上从 sdk 中找到了一种更简单的方法。结果发现每个 OpenXml 对象都有一个名为

OuterXml
的方法。

根据微软定义:

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

InnerXml: Gets or sets the markup that represents only the child elements of the current element.

好多了

所以我可以简单地做:

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;
 }

0
投票

在 OpenXML v3 中引入了一种更有效的方法:OpenXmlElementComparers

它会让您能够

OpenXmlElementComparers.Default.Equals(a,b)
。 还可以通过使用 OpenXmlElementEqualityOptions

创建来更精细地控制如何定义相等性

OuterXml 属性曾经是解决此问题的最简单方法。然而,由于如此处所述的大量分配,性能并不是很好。

© www.soinside.com 2019 - 2024. All rights reserved.