[英]Using XmlAttributeOverrides to change element names in object tree
我需要弄清楚如何使用从数据库中检索到的值作为我的元素名称来重命名生成的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;
}
}
因此,很显然,没有名为“ Medication”或“ User”的对象类型,必须从数据中推断出这些对象类型。 因此,我需要知道如何使用数据中的值来更改元素名称,但是我需要弄清楚如何对对象树进行爬网,以便根据关联的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更改每个元素名称。
提前致谢!
尽管我认为您可以通过使用自定义序列化来实现,但是我想提出一种不同的方法来使用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();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.