2013-12-16 1 views
1

Мне нужно выяснить, как переименовывать элементы и/или атрибуты в сгенерированном XML, используя значения, полученные из базы данных в качестве имен моих элементов.Использование XmlAttributeOverrides для изменения имен элементов в дереве объектов

Например, здесь потенциальный выход XML из моего текущего процесса:

<ArrayOfEntityTreeBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <EntityTreeBase EntityInfo="User"> 
    <Children> 
     <EntityTreeBase EntityInfo="User Medication"> 
     <Properties> 
      <EntityProperty CreatedDate="2013-11-14T16:41:12.75"> 
      <FieldName>Medication Name</FieldName> 
      <Value>Celebrex</Value> 
      </EntityProperty> 
      <EntityProperty CreatedDate="2013-12-04T14:08:58.597"> 
      <FieldName>Medication Dosage</FieldName> 
      <Value>20000MG</Value> 
      </EntityProperty> 
      <EntityProperty CreatedDate="2013-11-14T16:41:12.76"> 
      <FieldName>Medication Prescribed Date</FieldName> 
      <Value>08/01/2013</Value> 
      </EntityProperty> 
     </Properties> 
     </EntityTreeBase> 
     <EntityTreeBase EntityInfo="User Medication"> 
     <Properties> 
      <EntityProperty CreatedDate="2013-11-14T16:41:12.767"> 
      <FieldName>Medication Name</FieldName> 
      <Value>Aspirin</Value> 
      </EntityProperty> 
      <EntityProperty CreatedDate="2013-11-14T16:41:12.77"> 
      <FieldName>Medication Dosage</FieldName> 
      <Value>5 mg</Value> 
      </EntityProperty> 
      <EntityProperty CreatedDate="2013-11-14T16:41:12.78"> 
      <FieldName>Medication Prescribed Date</FieldName> 
      <Value>09/01/2013</Value> 
      </EntityProperty> 
     </Properties> 
     </EntityTreeBase> 
     <EntityTreeBase EntityInfo="User Medication"> 
     <Properties> 
      <EntityProperty CreatedDate="2013-11-14T16:41:12.783"> 
      <FieldName>Medication Name</FieldName> 
      <Value>Celebrex</Value> 
      </EntityProperty> 
      <EntityProperty CreatedDate="2013-11-14T16:41:12.793"> 
      <FieldName>Medication Dosage</FieldName> 
      <Value>50 mg twice a day</Value> 
      </EntityProperty> 
      <EntityProperty CreatedDate="2013-11-14T16:41:12.8"> 
      <FieldName>Medication Prescribed Date</FieldName> 
      <Value>10/01/2013</Value> 
      </EntityProperty> 
     </Properties> 
     </EntityTreeBase> 
    </Children> 
    <Properties> 
     <EntityProperty CreatedDate="2013-12-03T13:48:03.45"> 
     <FieldName>User First Name</FieldName> 
     <Value>John</Value> 
     </EntityProperty> 
     <EntityProperty CreatedDate="2013-12-03T11:36:31.423"> 
     <FieldName>User MI</FieldName> 
     <Value>Q</Value> 
     </EntityProperty> 
     <EntityProperty CreatedDate="2013-11-19T09:56:44.66"> 
     <FieldName>User Last Name</FieldName> 
     <Value>Public</Value> 
     </EntityProperty> 
     <EntityProperty CreatedDate="2013-11-14T16:41:12.803"> 
     <FieldName>User SSN</FieldName> 
     <Value>111-22-3333</Value> 
     </EntityProperty> 
    </Properties> 
    </EntityTreeBase> 
</ArrayOfEntityTreeBase> 

Что мне нужно, чтобы выполнить это:

<UserInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <User> 
    <UserMedications> 
     <UserMedication> 
     <MedicationProperties> 
      <MedicationProperty CreatedDate="2013-11-14T16:41:12.75"> 
      <FieldName>Medication Name</FieldName> 
      <Value>Celebrex</Value> 
      </MedicationProperty> 
      <MedicationProperty CreatedDate="2013-12-04T14:08:58.597"> 
      <FieldName>Medication Dosage</FieldName> 
      <Value>20000MG</Value> 
      </MedicationProperty> 
      <MedicationProperty CreatedDate="2013-11-14T16:41:12.76"> 
      <FieldName>Medication Prescribed Date</FieldName> 
      <Value>08/01/2013</Value> 
      </MedicationProperty> 
     </MedicationProperties> 
     </UserMedication> 
     <UserMedication> 
     <MedicationProperties> 
      <MedicationProperty CreatedDate="2013-11-14T16:41:12.767"> 
      <FieldName>Medication Name</FieldName> 
      <Value>Aspirin</Value> 
      </MedicationProperty> 
      <MedicationProperty CreatedDate="2013-11-14T16:41:12.77"> 
      <FieldName>Medication Dosage</FieldName> 
      <Value>5 mg</Value> 
      </MedicationProperty> 
      <MedicationProperty CreatedDate="2013-11-14T16:41:12.78"> 
      <FieldName>Medication Prescribed Date</FieldName> 
      <Value>09/01/2013</Value> 
      </MedicationProperty> 
     </MedicationProperties> 
     </UserMedication> 
     <UserMedication> 
     <MedicationProperties> 
      <MedicationProperty CreatedDate="2013-11-14T16:41:12.783"> 
      <FieldName>Medication Name</FieldName> 
      <Value>Celebrex</Value> 
      </MedicationProperty> 
      <MedicationProperty CreatedDate="2013-11-14T16:41:12.793"> 
      <FieldName>Medication Dosage</FieldName> 
      <Value>50 mg twice a day</Value> 
      </MedicationProperty> 
      <MedicationProperty CreatedDate="2013-11-14T16:41:12.8"> 
      <FieldName>Medication Prescribed Date</FieldName> 
      <Value>10/01/2013</Value> 
      </MedicationProperty> 
     </MedicationProperties> 
     </UserMedication> 
    </UserMedications> 
    <UserProperties> 
     <UserProperty CreatedDate="2013-12-03T13:48:03.45"> 
     <FieldName>User First Name</FieldName> 
     <Value>John</Value> 
     </UserProperty> 
     <UserProperty CreatedDate="2013-12-03T11:36:31.423"> 
     <FieldName>User MI</FieldName> 
     <Value>Q</Value> 
     </UserProperty> 
     <UserProperty CreatedDate="2013-11-19T09:56:44.66"> 
     <FieldName>User Last Name</FieldName> 
     <Value>Public</Value> 
     </UserProperty> 
     <UserProperty CreatedDate="2013-11-14T16:41:12.803"> 
     <FieldName>User SSN</FieldName> 
     <Value>111-22-3333</Value> 
     </UserProperty> 
    </UserProperties> 
    </User> 
</UserInformation> 

Вот мои объекты:

public class EntityProperty 
{ 
    [XmlIgnore] 
    public int FieldId { get; set; } 
    public string FieldName { get; set; } 
    [XmlIgnore] 
    public int FieldSortOrder { get; set; } 
    [XmlAttribute()] 
    public DateTime CreatedDate { get; set; } 
    [XmlIgnore] 
    public bool IsIterative { get; set; } 
    public string Value { get; set; } 
    public EntityTreeBase Entity { get; set; } 
    public EntityProperty() { } 
    public EntityProperty(int fieldId, string fieldName, int fieldSortOrder, DateTime createdDate, bool isIterative, string valueIn) 
    { 
     FieldId = fieldId; 
     FieldName = FieldName; 
     FieldSortOrder = fieldSortOrder; 
     CreatedDate = createdDate; 
     IsIterative = isIterative; 
     Value = valueIn; 
    } 
} 

public class EntityTreeBase 
{ 
    [XmlIgnore] 
    public long EntityId { get; set; } 
    [XmlIgnore] 
    public long? ParentEntityId { get; set; } 
    [XmlIgnore] 
    public int EntityDefinitionId { get; set; } 
    [XmlIgnore] 
    public int DestinationId { get; set; } 
    [XmlIgnore] 
    public int Level { get; set; } 
    [XmlAttribute("EntityInfo")] 
    public string EntityDefinitionName { get; set; } 
    public EntityTreeBaseCollection Children { get; set; } 
    public EntityPropertiesCollection Properties { get; set; } 
    public EntityTreeBase() { } 
    public EntityTreeBase(long entityId, long? parentEntityId, int entityDefinitionId, int destinationId, int level, string entityDefinitionName) 
    { 
     EntityId = entityId; 
     ParentEntityId = parentEntityId; 
     EntityDefinitionId = entityDefinitionId; 
     DestinationId = destinationId; 
     Level = level; 
     EntityDefinitionName = entityDefinitionName; 
    } 
    public bool HasChildren 
    { 
     get { return (Children != null && Children.Count > 0); } 
    } 
    public bool HasProperties 
    { 
     get { return (Properties != null && Properties.Count > 0); } 
    } 
    public static EntityTreeBase BuildTree(EntityTreeBaseCollection collection, EntityTreeBase parent) 
    { 
     parent.Properties = EntityPropertiesCollection.GetProperties(parent.DestinationId, parent.EntityId, parent.EntityDefinitionId); 
     parent.Children = new EntityTreeBaseCollection(); 
     foreach (EntityTreeBase item in EntityTreeBaseCollection.FindChildEntities(collection, parent.EntityId)) 
     { 
      parent.Children.Add(BuildTree(EntityTreeBaseCollection.GetChildren(item.EntityId, item.Level, item.DestinationId), item)); 
     } 
     if (!parent.HasChildren) 
     { 
      parent.Children = null; 
     } 
     if (!parent.HasProperties) 
     { 
      parent.Properties = null; 
     } 
     return parent; 
    } 
} 

Итак, как мы надеемся, нет никаких типов объектов, называемых «Лекарство» или «Пользователь», они должны быть выведены f данные. Поэтому мне нужно знать, как использовать значения из данных для изменения имен моих элементов, но мне нужно выяснить, как обходить дерево объектов, чтобы каждое имя элемента было изменено на основе связанного с ним объекта EntityDefinitionName. Я использую рекурсию для заполнения дерева объектов до сериализации. Я знаю, что следующий код работает, чтобы переименовать мой XmlRoot:

XmlAttributeOverrides xmlOverrides = new XmlAttributeOverrides(); 
XmlAttributes attribs = new XmlAttributes(); 
XmlRootAttribute rootAttr = new XmlRootAttribute(); 
rootAttr.ElementName = collection.Find(e => e.Level == 1).EntityDefinitionName.Replace(" ", ""); 
attribs.XmlRoot = rootAttr; 

Но мне нужно, чтобы выяснить, как изменить имя каждого элемента на основе EntityDefinitionName, связанную с этим элементом или узлом.

Заранее благодарен!

ответ

0

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

Эта таблица стилей превращает ваш входной XML до нужного вывода XML:

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
       exclude-result-prefixes="msxsl"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="ArrayOfEntityTreeBase"> 
     <UserInformation > 
     <xsl:apply-templates /> 
     </UserInformation> 
    </xsl:template> 

    <xsl:template match="EntityTreeBase[@EntityInfo='User']"> 
    <User> 
     <xsl:apply-templates /> 
    </User> 
    </xsl:template> 

    <xsl:template match="Children"> 
    <UserMedications> 
     <xsl:apply-templates /> 
    </UserMedications> 
    </xsl:template> 

    <xsl:template match="EntityTreeBase[@EntityInfo='User Medication']"> 
    <UserMedication> 
     <xsl:apply-templates /> 
    </UserMedication> 
    </xsl:template> 

    <xsl:template match="EntityTreeBase[@EntityInfo='User Medication']/Properties"> 
    <MedicationProperties> 
     <xsl:apply-templates /> 
    </MedicationProperties> 
    </xsl:template> 

    <xsl:template match="EntityTreeBase[@EntityInfo='User']/Properties"> 
    <UserProperties> 
     <xsl:apply-templates/> 
    </UserProperties> 
    </xsl:template> 

    <xsl:template match="EntityTreeBase[@EntityInfo='User']/Properties/EntityProperty"> 
    <xsl:element name="UserProperty"> 
     <xsl:copy-of select="@*"/> 
     <xsl:copy-of select="*" /> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="EntityTreeBase[@EntityInfo='User Medication']/Properties/EntityProperty"> 
    <xsl:element name="MedicationProperty"> 
     <xsl:copy-of select="@*"/> 
     <xsl:copy-of select="*" /> 
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

Это код, который вы можете использовать пробеге преобразование в вашей C# код:

var xml = File.Open("input.xml", FileMode.Open); // or any stream 
var xslTrans = new XslCompiledTransform(); 
xslTrans.Load(XmlReader.Create(File.Open("yourxslfile.xlst", FileMode.Open))); 
var output = File.Create("output.xml"); // or a stream 
var xw = XmlWriter.Create(output); 
xslTrans.Transform(XmlReader.Create(xml), xw); 
xw.Close(); 
Смежные вопросы