XmlReader - Я должен отредактировать элемент и произвести новый

Linq к SQL с помощью таблицы на решение для класса:

http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/10/01/linq-to-sql-inheritance.aspx

Другие решения (такие как мой фаворит, LLBLGen) позволяют другие модели. Лично, мне нравится единственное решение для таблицы со столбцом различителя, но это, вероятно, потому что мы часто запрашиваем через иерархию наследования и таким образом рассматриваем его как нормальный запрос, тогда как запросы определенного типа только требуют "где" изменение.

Все сказали и сделанный, я лично чувствую, что отображение OO в таблицы ставит телегу впереди лошади. Были непрерывные заявления, что несоответствие импеданса между OO и отношениями было решено... и было много OO определенные базы данных. Ни один из них не сбросил мощную простоту отношения.

Вместо этого я склонен разрабатывать базу данных с приложением в памяти, отображать те таблицы на объекты и сборку оттуда. Некоторые находят это как потерю OO в процессе проектирования, но в моем уме слой данных не должен говорить достаточно высоко в Ваше приложение для влияния на дизайн систем высшего порядка, просто потому что Вы использовали реляционную модель для устройства хранения данных .

8
задан Phill Duffy 1 October 2009 в 07:43
поделиться

5 ответов

XmlReader / Writer - это потоки с последовательным доступом. Вам нужно будет прочитать на одном конце, обработать поток, как вы хотите, и записать его на другом конце. Преимущество состоит в том, что вам не нужно считывать все это в память и строить DOM, что вы получите с любым подходом на основе XmlDocument.

Этот метод должен помочь вам начать работу:

private static void PostProcess(Stream inStream, Stream outStream)
{
    var settings = new XmlWriterSettings() { Indent = true, IndentChars = " " };

    using (var reader = XmlReader.Create(inStream))
    using (var writer = XmlWriter.Create(outStream, settings)) {
        while (reader.Read()) {
            switch (reader.NodeType) {
                case XmlNodeType.Element:
                    writer.WriteStartElement(reader.Prefix, reader.Name, reader.NamespaceURI);
                    writer.WriteAttributes(reader, true);

                    //
                    // check if this is the node you want, inject attributes here.
                    //

                    if (reader.IsEmptyElement) {
                        writer.WriteEndElement();
                    }
                    break;

                case XmlNodeType.Text:
                    writer.WriteString(reader.Value);
                    break;

                case XmlNodeType.EndElement:
                    writer.WriteFullEndElement();
                    break;

                case XmlNodeType.XmlDeclaration:
                case XmlNodeType.ProcessingInstruction:
                    writer.WriteProcessingInstruction(reader.Name, reader.Value);
                    break;

                case XmlNodeType.SignificantWhitespace:
                    writer.WriteWhitespace(reader.Value);
                    break;
            }
        }
    }
}

Это не так чисто, как создание собственного XmlWriter, но я считаю, что это намного проще.

[EDIT]

Пример того, как вы открываете два потока одновременно, может выглядеть примерно так:

using (FileStream readStream = new FileStream(@"c:\myFile.xml", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write)) {
  using (FileStream writeStream = new FileStream(@"c:\myFile.xml", FileMode.OpenOrCreate, FileAccess.Write)) {
    PostProcess(readStream, writeStream);
  }
}
13
ответ дан 5 December 2019 в 12:59
поделиться

I fixed it using the following duct tape coding

    public XmlReader FixUpReader(XmlReader reader)
    {
       reader.MoveToContent();

        string xml = reader.ReadOuterXml();

        string dslVersion = GetDSLVersion();
        string Id = GetID();

        string processedValue = string.Format("<ExampleElement dslVersion=\"{1}\" Id=\"{2}\" ", dslVersion, Id);
        xml = xml.Replace("<ExampleElement ", processedValue);
        MemoryStream ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(xml));
        XmlReaderSettings settings = new XmlReaderSettings();

        XmlReader myReader = XmlReader.Create(ms);
        myReader.MoveToContent();
        return myReader;
    }

I feel dirty for doing it this way but it is working....

1
ответ дан 5 December 2019 в 12:59
поделиться

Вы не сможете легко сделать это с помощью XmlReader - по крайней мере, не без чтения всего XML-документа от читателя, поработать с ним и затем создать новый XmlReader из результата. Однако это лишает многих смысла использования XmlReader , а именно возможности потоковой передачи больших документов.

Вы можете потенциально унаследовать от XmlReader , перенаправляя большую часть вызовы методов к существующему считывателю, но перехватывая их там, где это необходимо, чтобы добавить дополнительные атрибуты и т. д. ... но я подозреваю, что код будет действительно довольно сложным и хрупким.

1
ответ дан 5 December 2019 в 12:59
поделиться

Я бы предпочел загрузить xml в объект XmlDocument, использовать коллекцию Attributes для изменения значения и вызвать метод Save для обновления этого значения. Приведенный ниже код работает для меня.

 public static void WriteElementValue ( string sName, string element, string value)
 {
  try
  {
    var node = String.Format("//elements/element[@name='{0}']", sName);
    var doc = new XmlDocument { PreserveWhitespace = true };
    doc.Load(configurationFileName);

    var nodeObject = doc.SelectSingleNode(node);

     if (nodeObject == null)
         throw new XmlException(String.Format("{0} path does not found any matching 
         node", node));

    var elementObject = nodeObject[element];

    if (elementObject != null)
    {
       elementObject.Attributes["value"].Value = value;
    }

    doc.Save(configurationFileName);
}
catch (Exception ex)
{
   throw new ExitLevelException(ex, false);
}

}

Я также заметил, что при использовании XmlWriter или XmlSerializer пробельные символы сохраняются неправильно, иногда это может раздражать

.
0
ответ дан 5 December 2019 в 12:59
поделиться
        string newvalue = "10";
        string presentvalue = "";
        string newstr = "";
        XmlReader xmlr = XmlReader.Create(new StringReader(str));

        while (xmlr.Read())
        {
            if (xmlr.NodeType == XmlNodeType.Element)
            {
                if (xmlr.Name == "priority")
                {
                    presentvalue = xmlr.ReadElementContentAsString();
                    newstr = str.Replace(presentvalue, newvalue);
                }
            }

        }

// newstr можно записать обратно в файл ... это отредактированный xml

-2
ответ дан 5 December 2019 в 12:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: