【问题标题】:Using XmlAttributeOverrides to change element names in object tree使用 XmlAttributeOverrides 更改对象树中的元素名称
【发布时间】:2013-12-16 17:15:00
【问题描述】:

我需要弄清楚如何使用从数据库中检索到的值作为我的元素名称来重命名生成的 XML 中的元素和/或属性。

例如,这是我当前流程的潜在 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;
    }
}

因此,正如希望显而易见的那样,没有名为“药物”或“用户”的对象类型,这些必须从数据中推断出来。所以我需要知道如何使用数据中的值来更改我的元素名称,但我需要弄清楚如何爬取对象树,以便根据关联的 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 更改每个元素的名称。

提前致谢!

【问题讨论】:

    标签: c# .net xml xml-serialization xml-attribute


    【解决方案1】:

    虽然我认为您可以通过使用自定义序列化来实现这一点,但我想提出一种不同的方法来使用 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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多