XmlSerializer генерирует исключение InvalidOperationException при наличии префикса пространства имен в атрибуте - PullRequest
3 голосов
/ 27 июля 2010

Я пытаюсь прочитать файл XML, который содержит следующий элемент:

<ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT16" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">

Мой класс для описания этого узла выглядит так:

public ref class FIBEXCodedType 
 {
 public:
  [XmlAttribute("ho:BASE-DATA-TYPE")]
  property String^ BaseDataType;

  [XmlAttribute("CATEGORY")]
  property String^ Category;

  [XmlAttribute("ENCODING")]
  property String^ Encoding;

  FIBEXCodedType(void);
 };

Я получаю исключение InvalidOperationException от XmlSerializer.ctor говорит мне:

"Ungültiges Namenszeichen в" ho: BASE-DATA-TYPE "."(это можно перевести как «недопустимый символ в: 'ho: BASE-DATA-TYPE'").

Я также попробовал следующее:

[XmlAttribute("BASE-DATA-TYPE", Namespace="http://www.asam.net/xml")]
property String^ BaseDataType;

Но это не сработалоили.На этот раз без сообщения об ошибке, но модульный тест не показывает, что для свойства все еще установлено значение «null».

Я полностью застрял с этим.Так что любая помощь приветствуется

заранее спасибо

РЕДАКТИРОВАТЬ: еще немного XML

<?xml version="1.0" ?>
<fx:FIBEX xmlns:fx="http://www.asam.net/xml/fbx" xmlns:ho="http://www.asam.net/xml" xmlns:can="http://www.asam.net/xml/fbx/can" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="fibex4can.xsd" VERSION="3.1.0">

<fx:CODING ID="codingSpeed">
    <ho:SHORT-NAME>CodingSpeed</ho:SHORT-NAME>
    <ho:DESC>Coding for speed values within this system.</ho:DESC>
    <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT16" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
    <ho:BIT-LENGTH>16</ho:BIT-LENGTH>
    </ho:CODED-TYPE>
</fx:CODING>

1 Ответ

2 голосов
/ 27 июля 2010

переписать весь ответ после редактирования OP

Мое первоначальное понимание ошибки было неверным. Ошибка возникает при инициализации сериализатора, , а не , когда вы читаете ваш XML. Вы не можете использовать двоеточие : в имени. Если вы указываете пространство имен, не указывайте префикс. На самом деле, вы вряд ли когда-либо будете указывать префикс (который является просто заполнителем для пространства имен).

После этого вы уже заметили, что значение заканчивается null. Причина в том, что сериализатор по умолчанию имеет неквалифицированные атрибуты. Если у вас есть квалифицированные атрибуты, предполагается, что пространство имен атрибута отличается от пространства имен элемента. Это будет работать:

<!-- this works (if namespaces are indeed different -->
<ho:CODED-TYPE fx:BASE=DATA-TYPE="A_UINT16"...>

<!-- this works, unqualified name takes namespace of parent element -->
<ho:CODED-TYPE BASE=DATA-TYPE="A_UINT16"...>

<!-- this fails, because XmlSerializer does not expect qualified attributes -->
<ho:CODED-TYPE ho:BASE=DATA-TYPE="A_UINT16"...>

Это кажется странной ошибкой. Вот несколько похожий отчет об этом n на MSDN, который помог мне найти решение. Просто пометьте атрибут как квалифицированный. Следующее работает с вашим входным XML (примечание XmlSchemaForm.Qualified):

[XmlRoot(ElementName = "FIBEX", Namespace = "http://www.asam.net/xml/fbx")]
public class FIBEX
{
    [XmlElement("CODING", Namespace = "http://www.asam.net/xml/fbx")]
    public FIBEXCoding Coding { get; set; }
}

public class FIBEXCoding
{
    [XmlElement("SHORT-NAME", Namespace = "http://www.asam.net/xml")]
    public string ShortName { get; set; }

    [XmlElement("DESC", Namespace = "http://www.asam.net/xml")]
    public string ShortDescription { get; set; }

    [XmlElement("CODED-TYPE", Namespace = "http://www.asam.net/xml")]
    public FIBEXCodedType Codedtype { get; set; }
}

public class FIBEXCodedType
{

    [XmlAttribute("BASE-DATA-TYPE", 
        Namespace = "http://www.asam.net/xml",
        Form=XmlSchemaForm.Qualified)]
    public string BaseDataType { get; set; }

    [XmlAttribute("CATEGORY")]
    public string Category { get; set; }

    [XmlAttribute("ENCODING")]
    public string Encoding { get; set; }

    [XmlElement("BIT-LENGTH", Namespace = "http://www.asam.net/xml")]
    public int BitLength { get; set; }
}
...