C# 使用XmlAttributeOverrides更改对象树中的元素名称

C# 使用XmlAttributeOverrides更改对象树中的元素名称,c#,.net,xml,xml-serialization,xml-attribute,C#,.net,Xml,Xml Serialization,Xml Attribute,我需要弄清楚如何使用从数据库中检索的值作为元素名重命名生成的XML中的元素和/或属性 例如,以下是我当前流程的潜在XML输出: <ArrayOfEntityTreeBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <EntityTreeBase EntityInfo="User"> <Childr

我需要弄清楚如何使用从数据库中检索的值作为元素名重命名生成的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>
因此,很明显,没有名为“药物”或“用户”的对象类型,这些类型必须从数据中推断出来。因此,我需要知道如何使用数据中的值来更改元素名称,但我需要知道如何爬网对象树,以便根据关联的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>
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;
<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>
 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();