0

对于一个 C# 项目,我正在查询一个 API,它返回一个类似于以下内容的 XML:

<itemlist>
  <item attrib1="Value1" attrib2="Value2"... attrib15="Value15">
    <sometypeinfo1 attrib1="Value1" attrib2="Value2"... attrib15="Value15">
      <subelement>
        <someproperty attrib1="Value1" attrib2="Value2"/>
        <someproperty attrib1="Value1" attrib2="Value2"/>
        <someproperty attrib1="Value1" attrib2="Value2"/>
      </subelement>
    </sometypeinfo1>
    <sometypeinfo2>
      <subelement attrib1="Value1" attrib2="Value2">
        <someproperty>
          <somedescription attrib1="Value1" attrib2="Value2"/>
          <somedescription attrib1="Value1" attrib2="Value2"/>
        </someproperty>
      </subelement>
    </sometypeinfo2>
    <sometypeinfo3 attrib1="Value1" attrib2="Value2"/>
    <sometypeinfo4>
      <someproperty attrib1="Value1" attrib2="Value2"/>
    </sometypeinfo4>
    <sometypeinfo5>
      <someproperty attrib="somevalue"/>
    </sometypeinfo5>
    <somemodifiers>
      <somemodifier attrib1="Value1" attrib2="Value2"/>
      <somemodifier attrib1="Value1" attrib2="Value2"/>
      <somemodifier attrib1="Value1" attrib2="Value2"/>
    </somemodifiers>
    <someflags>
      <someflag attrib="somevalue"/>
      <someflag attrib="somevalue"/>
      <someflag attrib="somevalue"/>
    </someflags>
  </item>
  <item>
  .
  .
  .
  </item>
</itemlist>

它基本上是一个包含约 100 个项目/文件的列表,每个项目都有很多描述、属性等。现在,这并不罕见。我无法将其映射到类或数据集中。例如这一行

<sometypeinfo1 attrib1="Value1" attrib2="Value2"... attrib15="Value15">

一个项目可能错过 attrib1,另一个 attrib2,第三个可能有全部 15 个等。

与“Someflags”相同,一个项目可以有 5 个“someflag”,下一个只有 2 个。等等。每个元素或属性都可以在那里,但不是必须的。所以它们都共享一个元素/属性池,这就是我陷入序列化等问题的地方。

是的,我是新手。但是从我到目前为止所学到的知识来看,模式必须具有所有元素/属性才能正确映射 XML?

唯一想到的是编写另一个工具来收集所有可能的元素等,然后编写一个包含所有内容的类,首先将所有内容设为 NULL,然后只解析 XML,覆盖在实际项目中找到的所有内容。

4

2 回答 2

0

大多数 XML 解析工具将元素的属性表示为一个集合,您可以迭代该集合。

它们也将子元素表示为一个集合。

下面是一些使用我选择的 XML 解析类的示例语法,但 c# 有多个内置选项,您可以在闲暇时探索。

        XmlDocument doc = new XmlDocument();
        doc.Load("myXML.xml");
        XmlNode node = doc.SelectSingleNode("//sometypeinfo1");

        foreach (XmlAttribute a in node.Attributes)
        {
            Console.Write(a.Name);
            Console.Write(a.Value);
        }

这是我在此处使用的有关 XPATH 的进一步文档。

于 2012-09-25T19:59:55.287 回答
0

我们遇到了类似的问题,并使用 XSLT 样式表将原始 XML 的属性转换为新 XML 文档中的元素(将 XSLT 加载到 XslTransform 对象中以转换原始 XML)。然后将新的 XML 文档读入 DataSet 对象。

请参阅 msdn 文章: Inferring DataSet Relational Structure from XMLInferring Relationships

将上面的 XML 从属性转换为元素的部分 XSLT 示例:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" omit-xml-declaration="no"/>
    <xsl:template match="/">
        <xsl:apply-templates select="/itemlist"/>
    </xsl:template>
    <xsl:template match="itemlist">
        <xsl:element name="itemlist">
            <xsl:apply-templates select="item"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="item">
        <xsl:element name="item">
            <xsl:element name="attrib1">
                <xsl:value-of select="@attrib1"/>
            </xsl:element>
            <xsl:element name="attrib2">
                <xsl:value-of select="@attrib2"/>
            </xsl:element>
            <xsl:element name="attrib3">
                <xsl:value-of select="@attrib3"/>
            </xsl:element>
            <!-- continue above pattern for all 15 attributes. -->
            <xsl:apply-templates select="sometypeinfo1"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="sometypeinfo1">
        <xsl:element name="sometypeinfo1">
            <xsl:element name="attrib1">
                <xsl:value-of select="@attrib1"/>
            </xsl:element>
            <xsl:element name="attrib2">
                <xsl:value-of select="@attrib2"/>
            </xsl:element>
            <xsl:element name="attrib3">
                <xsl:value-of select="@attrib3"/>
            </xsl:element>
                <!-- continue above pattern for all 15 attributes. -->
                <xsl:apply-templates select="subelement"/>
            </xsl:element>
        </xsl:element>
    </xsl:template>
    <xsl:template match="subelement">...
于 2013-10-22T23:09:44.840 回答