【问题标题】:The XML element 'tr' from namespace '' is already present in the current scope命名空间“”中的 XML 元素“tr”已存在于当前范围内
【发布时间】:2017-09-26 09:16:04
【问题描述】:

我正在尝试通过将我的对象序列化为 XML 来构建 CDA 文档,这是给我带来一些麻烦的 XML 部分:

<component>
    <section>
        <templateId root='2.16.840.1.113883.10.20.1.11'/>
        <templateId root='1.3.6.1.4.1.19376.1.5.3.1.3.6'/>
        <!--<id root='' extension=''/>-->
        <code code="11450-4" displayName="PROBLEM LIST" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC"/>
        <title>Active Problem - Problem List</title>
        <text>
            <table>
                <thead>
                    <tr>
                        <th>Problem</th>
                        <th>Code</th>
                        <th>Code System</th>
                        <th>Start Date</th>
                        <th>Status</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>Asthma</td>
                        <td>195967001</td>
                        <td>SNOMED CT</td>
                        <td></td>
                        <td>Active</td>
                    </tr>
                    <tr>
                        <td>Costal chondritis</td>
                        <td>64109004</td>
                        <td>SNOMED CT</td>
                        <td></td>
                        <td>Active</td>
                    </tr>
                    <tr>
                        <td>No impairment</td>
                        <td>66557003</td>
                        <td>SNOMED CT</td>
                        <td></td>
                        <td>Active</td>
                    </tr>
                </tbody>
            </table>
        </text>
    </section>
</component>

这是我用于序列化它的 C# 类:

public class Section
{
    [XmlElement("templateId")]
    public List<IdElement> TemplateIds { get; set; }
    [XmlElement("code")]
    public CodeElement Code { get; set; }
    [XmlElement("title")]
    public string Title { get; set; }
    [XmlElement("text")]
    public Text Text { get; set; }
}
public class Text
{
    [XmlElement("table")]
    public Table.Table Table { get; set; }

    [XmlArray("list")]
    [XmlArrayItem("item")]
    public List<string> List { get; set; }

    [XmlElement("paragraph")]
    public List<string> Paragraphs { get; set; }
}
public class Table
{
    [XmlElement("thead")]
    public TRow Header { get; set; }
    [XmlElement("tbody")]
    public TRow Body { get; set; }
}
public class TRow
{
    [XmlArray(ElementName = "tr", Namespace = "")]
    [XmlArrayItem("td")]
    public List<string> RowData { get; set; }

    [XmlArray(ElementName = "tr", Namespace = "")]
    [XmlArrayItem("th")]
    public List<string> HeaderData { get; set; }
}

但是当我现在尝试序列化我的 CDA 对象时,它说类型 tr 已经存在于命名空间中,所以我猜这种 XML 表已经存在,但我不能找不到正确的方法。 有没有办法解决这个问题?

这是错误日志(没有堆栈跟踪):

System.InvalidOperationException:反映类型时出现错误 'Project.Cda.Core.ClinicalDocument'。 ---> System.InvalidOperationException:出现错误反映 属性“组件”。 ---> System.InvalidOperationException:有 反映类型“Project.Cda.Core.Components.BaseComponent”的错误。 ---> System.InvalidOperationException:反映属性“组件”时出现错误。 ---> System.InvalidOperationException:有 是反映类型“Project.Cda.Core.Components.Component”的错误。 ---> System.InvalidOperationException:反映属性“部分”时出现错误。 ---> System.InvalidOperationException:有 反映类型“Project.Cda.Core.Components.Section”的错误。 ---> System.InvalidOperationException:出现错误反映 属性“文本”。 ---> System.InvalidOperationException:有一个 反映类型“Project.Cda.Core.Components.Text”的错误。 ---> System.InvalidOperationException:出现错误反映 属性“表”。 ---> System.InvalidOperationException:有一个 反映类型“Project.Cda.Core.Components.Table.Table”的错误。 ---> System.InvalidOperationException:出现错误反映 属性“标题”。 ---> System.InvalidOperationException:有一个 反映类型“Project.Cda.Core.Components.Table.TRow”的错误。 ---> System.InvalidOperationException:出现错误反映 属性“标题数据”。 ---> System.InvalidOperationException:XML 命名空间''中的元素'tr'已经存在于当前 范围。使用 XML 属性指定另一个 XML 名称或命名空间 元素。

【问题讨论】:

  • TRow 中,您在RowDataHeaderData 上都有[XmlArray(ElementName = "tr", Namespace = "")]。那是行不通的。
  • @dbc 嗯,谢谢,我会尝试别的。为 Header 和 Body 数据创建单独的类是我唯一的选择吗?
  • 这是迄今为止最简单的。其他选项包括 1) 使用[XmlChoiceIdentifierAttribute] 设置enum 数组,指示&lt;tr&gt; 子元素是&lt;td&gt; 还是&lt;th&gt;。 2) 实现IXmlSerializable。 (不要这样做!) 3)在[XmlAnyElement] 属性内使用嵌套序列化做一些技巧,如图所示,例如here.
  • 好的,谢谢,使用相同的元素名称会更简洁,但它可以工作,谢谢!

标签: c# xml serialization .net-core


【解决方案1】:

您收到错误是因为,在TRow,您有

[XmlArray(ElementName = "tr", Namespace = "")]

RowDataHeaderData 上。那是行不通的——您试图为两个不同的属性指定相同的元素名称,因此得到您看到的错误,即 命名空间 '' 中的 XML 元素 'tr' 已经存在于当前范围。

此外,您的模型还有一个问题。 &lt;tbody&gt; 中的 &lt;tr&gt; 元素重复,但您的数据模型只允许每个主体有一个 &lt;tr&gt; 元素。

下面通过引入一个中间 TablePart 来表示表的标题和正文部分来解决这两个问题:

public class Table
{
    [XmlElement("thead")]
    public TablePart Header { get; set; }

    [XmlElement("tbody")]
    public TablePart Body { get; set; }
}

public class TablePart
{
    [XmlElement(ElementName = "tr", Namespace = "")]
    public List<TableRow> RowData { get; set; }
}

public class TableRow
{
    [XmlElement("td")]
    public List<string> Data { get; set; }

    [XmlElement("th")]
    public List<string> Headers { get; set; }
}

示例fiddle

【讨论】:

    猜你喜欢
    • 2010-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    相关资源
    最近更新 更多