C # Parse xml Attriubte с именем a и написать его с именем b - PullRequest
0 голосов
/ 25 февраля 2011

У меня есть XML dom

<xml>
<ElementA/>
<xml>

Теперь мой xml изменился

<xml>
<ElementB/>
<xml> 

Значение ElementB a A является симметричным, но у меня есть пара файлов с ElementA и я должен перенести их в ElementB

Я работаю с XmlSerializer

Можно ли прочитать два узла в один параметр и записать их в одно имя атрибута, например

[XmlElement("ElementB")]
[XmlElement("ElementA")] // Writing this version only somehow 
  public float Rating
  { get; set; }

Ответы [ 2 ]

2 голосов
/ 27 февраля 2011

Я использовал Linq to XML ( System.Xml.Linq ), чтобы с большим успехом выполнять такую ​​работу по миграции схем в прошлом. Ваш код будет выглядеть примерно так:

XDocument doc = XDocument.Load("<path to input xml document>");
foreach (var element in doc.Descendants("AttributeA"))
{
    element.Name = "AttributeB";
}
doc.Save("<path to output xml document>");

По сути, вы просто читаете весь документ в XDocument и находите нужные вам узлы через Linq, манипулируете их значениями и записываете измененный XDocument обратно на диск. Затем, если вы все еще хотите использовать сериализацию Xml, вы снова прочитаете этот документ с диска и продолжите обработку, как и раньше.

1 голос
/ 27 февраля 2011

Вы можете делать то, что хотите, с помощью переопределений атрибутов XML.По сути, вы можете применять атрибуты XML Serialization к сериализатору во время выполнения.

См. Статью MSDN

Ниже приведен пример кода для использования переопределений атрибутов XML при сериализации XML.

public class DTO
{
    [XmlIgnore]
    public string additionalInformation;

    [XmlElement(Order=1)]
    public DateTime stamp;

    [XmlElement(Order=2)]
    public string name;

    [XmlElement(Order=3)]
    public double value;

    [XmlElement(Order=4)]
    public int index;
}


public class OverridesDemo
{
    public void Run()
    {
        DTO dto = new DTO {
            additionalInformation = "This information will be serialized separately",
            stamp = DateTime.UtcNow,
            name = "Marley",
            value = 72.34,
            index = 7
        };

        // this will allow us to omit the xmlns:xsi namespace
        var ns = new XmlSerializerNamespaces();
        ns.Add( "", "" );

        XmlSerializer s1 = new XmlSerializer(typeof(DTO));

        var builder = new System.Text.StringBuilder();
        var settings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent= true };

        Console.WriteLine("\nSerialize using the in-line (compile-time) attributes: ");
        using ( XmlWriter writer = XmlWriter.Create(builder, settings))
        {
            s1.Serialize(writer, dto, ns);
        }
        Console.WriteLine("{0}",builder.ToString());
        Console.WriteLine("\n");


        // use a default namespace
        ns = new XmlSerializerNamespaces();
        string myns = "urn:www.example.org";
        ns.Add( "", myns );

        XmlAttributeOverrides overrides = new XmlAttributeOverrides();

        XmlAttributes attrs = new XmlAttributes();
        // override the (implicit) XmlRoot attribute
        XmlRootAttribute attr1 = new XmlRootAttribute
            {
                Namespace = myns,
                ElementName = "DTO-Annotations",
            };
        attrs.XmlRoot = attr1;

        overrides.Add(typeof(DTO), attrs);
        // "un-ignore" the first property
        // define an XmlElement attribute, for a type of "String", with no namespace
        var a2 = new XmlElementAttribute(typeof(String)) { ElementName="note", Namespace = myns };

        // add that XmlElement attribute to the 2nd bunch of attributes
        attrs = new XmlAttributes();
        attrs.XmlElements.Add(a2);
        attrs.XmlIgnore = false;

        // add that bunch of attributes to the container for the type, and
        // specifically apply that bunch to the "Label" property on the type.
        overrides.Add(typeof(DTO), "additionalInformation", attrs);

        // ignore the other properties

        // add the XmlIgnore attribute to the 2nd bunch of attributes
        attrs = new XmlAttributes();
        attrs.XmlIgnore = true;

        // add that bunch of attributes to the container for the type, and
        // specifically apply that bunch to the "Label" property on the type.
        overrides.Add(typeof(DTO), "stamp", attrs);
        overrides.Add(typeof(DTO), "name", attrs);
        overrides.Add(typeof(DTO), "value", attrs);
        overrides.Add(typeof(DTO), "index", attrs);

        XmlSerializer s2 = new XmlSerializer(typeof(DTO), overrides);

        Console.WriteLine("\nSerialize using the override attributes: ");
        builder.Length = 0;
        using ( XmlWriter writer = XmlWriter.Create(builder, settings))
        {
            s2.Serialize(writer, dto, ns);
        }
        Console.WriteLine("{0}",builder.ToString());
        Console.WriteLine("\n");
    }

Вы можете использовать переопределения для сериализации или десериализации.

...