none
Еще вопрос по XML RRS feed

  • Вопрос

  • я пытаюсь создать такой атрибут: xmlns='http://schemas.microsoft.com/client/2007' и получаю ошибку:

    Префикс "xmlns" зарезервирован для использования XML.

    XmlWriter xw; ...

    xw.WriteAttributeString(atr.Name, atr.Ns, atr.Value);


    27 апреля 2012 г. 13:30

Ответы

  • Можно попробовать так:

    xw.WriteStartElement("UserControl", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    
    xw.WriteAttributeString("x", "Class", "http://schemas.microsoft.com/winfx/2006/xaml", "Site.SilverlightControl1");
    
    xw.WriteAttributeString("Width", "auto");
    xw.WriteAttributeString("Height", "auto");
    
    xw.WriteAttributeString("xmlns", "fast", null, "clr-namespace:Fast;assembly=Fast.Client.Core");
    xw.WriteAttributeString("xmlns", "Generic", null, "clr-namespace:System.Collections.Generic;assembly=mscorlib");
    
    xw.WriteEndElement();
    На выходе получим вышеуказанный xml (сразу отмечу, что порядок следования атрибутов и деклараций пространств имён в документах xml не важен).

    Пространство имён по умолчанию, без префикса, здесь задаётся при создании стартового тэга элемента. Пространство имён с префиксом x создаётся автоматически, при указании его в атрибуте Class.

    Две другие декларации неймспейсов создаём вручную, как атрибуты. И я не уверен, что это правильный подход.

    • Предложено в качестве ответа Petalvik 29 апреля 2012 г. 11:18
    • Помечено в качестве ответа Max Charp 3 мая 2012 г. 5:58
    27 апреля 2012 г. 22:03
  • Этот код пишет xml через XmlWellformedWriter, который обращается с нейспейсами немного не так, как XmlTextWriter. Точнее, это именно XmlTextWriter немного нестандартно пишет неймспейсы, о чем расписано у него в секции remarks.

    Для XmlWellformedWriter придется передавать неймспейс параметром в WriteStartElement.

    • Помечено в качестве ответа Max Charp 27 апреля 2012 г. 19:38
    27 апреля 2012 г. 18:12
  • Я дополнительно проштудировал MSDN, прошёлся по другим ресурсам типа Stackoverflow, помучал Google, и теперь достаточно уверенно могу сказать, что код в моём предыдущем сообщении правилен. Я сильно сомневался, что декларации пространств имён можно создавать как простые атрибуты. Однако, так и не нашёл ни в документации, ни где-либо ещё иных способов. Стало быть, так и нужно делать.
    • Помечено в качестве ответа Max Charp 3 мая 2012 г. 8:44
    29 апреля 2012 г. 11:17

Все ответы

  • Не совсем понятно что именно передается в name, ns и value. Но такой аттрибут можно записать примерно так:

                xw.WriteAttributeString("xmlns", null, "http://schemas.microsoft.com/client/2007");
                // или
                xw.WriteAttributeString("xmlns", "http://schemas.microsoft.com/client/2007");
    

    27 апреля 2012 г. 14:00
  • Вот именно так создать не удается.

            void test()
            {
                var set = new XmlWriterSettings()
                {
                    Encoding = Encoding.Unicode,
                    ConformanceLevel = ConformanceLevel.Auto,
                    OmitXmlDeclaration = true,
                    Indent = true,
                    
                    IndentChars = "    ",
                    NewLineChars = "\r\n"
                };
                
                var mem = new MemoryStream();
                var xw = XmlWriter.Create(mem, set);
                
                xw.WriteStartDocument();
    
                xw.WriteStartElement("Root");
                
                xw.WriteAttributeString("xmlns", null, "http://schemas.microsoft.com/client/2007");
                // или
                //xw.WriteAttributeString("xmlns", "http://schemas.microsoft.com/client/2007");
    
                xw.WriteEndElement();
    
                xw.WriteEndDocument();
    
                xw.Flush();
                xw.Close();
            }


    Ошибка:

    Префикс "" не может быть переопределен с "" на "http://schemas.microsoft.com/client/2007" внутри того же начального тега элемента.

    Во втором случае:

    Префикс "" не может быть переопределен с "" на "http://schemas.microsoft.com/client/2007" внутри того же начального тега элемента.

    PS: версия фреймворка SL4

    27 апреля 2012 г. 16:01
  • Этот код пишет xml через XmlWellformedWriter, который обращается с нейспейсами немного не так, как XmlTextWriter. Точнее, это именно XmlTextWriter немного нестандартно пишет неймспейсы, о чем расписано у него в секции remarks.

    Для XmlWellformedWriter придется передавать неймспейс параметром в WriteStartElement.

    • Помечено в качестве ответа Max Charp 27 апреля 2012 г. 19:38
    27 апреля 2012 г. 18:12
  • Спасибо, но а если мне нужно несколько неймспейсов записать? Например как здесь:

    <UserControl x:Class="Site.SilverlightControl1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="auto" Height="auto"

    xmlns:fast="clr-namespace:Fast;assembly=Fast.Client.Core"

    xmlns:Generic="clr-namespace:System.Collections.Generic;assembly=mscorlib">


    • Изменено Max Charp 27 апреля 2012 г. 19:40
    27 апреля 2012 г. 19:38
  • Можно попробовать так:

    xw.WriteStartElement("UserControl", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    
    xw.WriteAttributeString("x", "Class", "http://schemas.microsoft.com/winfx/2006/xaml", "Site.SilverlightControl1");
    
    xw.WriteAttributeString("Width", "auto");
    xw.WriteAttributeString("Height", "auto");
    
    xw.WriteAttributeString("xmlns", "fast", null, "clr-namespace:Fast;assembly=Fast.Client.Core");
    xw.WriteAttributeString("xmlns", "Generic", null, "clr-namespace:System.Collections.Generic;assembly=mscorlib");
    
    xw.WriteEndElement();
    На выходе получим вышеуказанный xml (сразу отмечу, что порядок следования атрибутов и деклараций пространств имён в документах xml не важен).

    Пространство имён по умолчанию, без префикса, здесь задаётся при создании стартового тэга элемента. Пространство имён с префиксом x создаётся автоматически, при указании его в атрибуте Class.

    Две другие декларации неймспейсов создаём вручную, как атрибуты. И я не уверен, что это правильный подход.

    • Предложено в качестве ответа Petalvik 29 апреля 2012 г. 11:18
    • Помечено в качестве ответа Max Charp 3 мая 2012 г. 5:58
    27 апреля 2012 г. 22:03
  • Я дополнительно проштудировал MSDN, прошёлся по другим ресурсам типа Stackoverflow, помучал Google, и теперь достаточно уверенно могу сказать, что код в моём предыдущем сообщении правилен. Я сильно сомневался, что декларации пространств имён можно создавать как простые атрибуты. Однако, так и не нашёл ни в документации, ни где-либо ещё иных способов. Стало быть, так и нужно делать.
    • Помечено в качестве ответа Max Charp 3 мая 2012 г. 8:44
    29 апреля 2012 г. 11:17
  • Код правилен, но вопрос скорее был в том, почему от способа создания - new XmlTextWriter или XmlWriter.Create зависит его реакция на запись неймспейса с пустым префиксом. XmlTextWriter позволяет определить неймспейс для уже записанного через WriteStartElement, вызовом xw.WriteAttributeString("xmlns", "http://schemas.microsoft.com/client/2007"). А объект из XmlWriter.Create - уже нет, кидает исключение. Хотя в документации сказано "лучше использовать .Create, он даст вам full advantage".
    29 апреля 2012 г. 14:08