Sort a complex XML based on inner most child - c#

I have a XML file containing data as shown below-
<?xml version="1.0" encoding="utf-8"?>
<Root>
<RootInner>
<NodesMain>
<Main>
<Modules>
<Module>
<Description>
<Child>
<Descriptionettings>
<setting name="ChildId" value="22" />
<setting name="ChildName" value="Child_1" />
<setting name="Capacity" value="100" />
<setting name="ChildType" value="DefaultChild" />
</Descriptionettings>
</Child>
<Child>
<Descriptionettings>
<setting name="ChildId" value="33" />
<setting name="ChildName" value="Reject" />
<setting name="Capacity" value="200" />
<setting name="ChildType" value="Reject" />
</Descriptionettings>
</Child>
</Description>
<Header>
<setting name="ModuleName" value="CC" />
<setting name="ModuleType" value="CC" />
<setting name="ModulePosition" value="3" />
</Header>
</Module>
<Module>
<Description>
<Child>
<Descriptionettings>
<setting name="ChildId" value="19" />
<setting name="ChildName" value="Child_1" />
<setting name="Capacity" value="100" />
<setting name="ChildType" value="DefaultChild" />
</Descriptionettings>
</Child>
<Child>
<Descriptionettings>
<setting name="ChildId" value="18" />
<setting name="ChildName" value="Reject" />
<setting name="Capacity" value="200" />
<setting name="ChildType" value="Reject" />
</Descriptionettings>
</Child>
</Description>
<Header>
<setting name="ModuleName" value="AA" />
<setting name="ModuleType" value="AA" />
<setting name="ModulePosition" value="1" />
</Header>
</Module>
<Module>
<Description>
<Child>
<Descriptionettings>
<setting name="ChildId" value="OC11" />
<setting name="ChildName" value="OC11" />
<setting name="Capacity" value="100" />
<setting name="ChildType" value="SDMChild" />
</Descriptionettings>
</Child>
<Child>
<Descriptionettings>
<setting name="ChildId" value="OC14" />
<setting name="ChildName" value="OC14" />
<setting name="Capacity" value="100" />
<setting name="ChildType" value="SDMChild" />
</Descriptionettings>
</Child>
</Description>
<Header>
<setting name="ModuleName" value="BB" />
<setting name="ModuleType" value="BB" />
<setting name="ModulePosition" value="2" />
</Header>
</Module>
</Modules>
</Main>
</NodesMain>
</RootInner>
</Root>
I want to sort the element by "ModulePosition" in C#.Net. Final output should be as follows. Sample code tried by me posted below
<Root>
<RootInner>
<NodesMain>
<Main>
<Modules>
<Module>
<Description>
<Child>
<Descriptionettings>
<setting name="ChildId" value="19" />
<setting name="ChildName" value="Child_1" />
<setting name="Capacity" value="100" />
<setting name="ChildType" value="DefaultChild" />
</Descriptionettings>
</Child>
<Child>
<Descriptionettings>
<setting name="ChildId" value="18" />
<setting name="ChildName" value="Reject" />
<setting name="Capacity" value="200" />
<setting name="ChildType" value="Reject" />
</Descriptionettings>
</Child>
</Description>
<Header>
<setting name="ModuleName" value="AA" />
<setting name="ModuleType" value="AA" />
<setting name="ModulePosition" value="1" />
</Header>
</Module>
<Module>
<Description>
<Child>
<Descriptionettings>
<setting name="ChildId" value="OC11" />
<setting name="ChildName" value="OC11" />
<setting name="Capacity" value="100" />
<setting name="ChildType" value="SDMChild" />
</Descriptionettings>
</Child>
<Child>
<Descriptionettings>
<setting name="ChildId" value="OC14" />
<setting name="ChildName" value="OC14" />
<setting name="Capacity" value="100" />
<setting name="ChildType" value="SDMChild" />
</Descriptionettings>
</Child>
</Description>
<Header>
<setting name="ModuleName" value="BB" />
<setting name="ModuleType" value="BB" />
<setting name="ModulePosition" value="2" />
</Header>
</Module>
<Module>
<Description>
<Child>
<Descriptionettings>
<setting name="ChildId" value="22" />
<setting name="ChildName" value="Child_1" />
<setting name="Capacity" value="100" />
<setting name="ChildType" value="DefaultChild" />
</Descriptionettings>
</Child>
<Child>
<Descriptionettings>
<setting name="ChildId" value="33" />
<setting name="ChildName" value="Reject" />
<setting name="Capacity" value="200" />
<setting name="ChildType" value="Reject" />
</Descriptionettings>
</Child>
</Description>
<Header>
<setting name="ModuleName" value="CC" />
<setting name="ModuleType" value="CC" />
<setting name="ModulePosition" value="3" />
</Header>
</Module>
</Modules>
</Main>
</NodesMain>
</RootInner>
</Root>
I am using XDocument to load contents and orderby linq expression to sort. But the results are not accurate, sample code below
var documents2 = xDoc.Descendants("Module").OrderBy(x => (int)(x.Elements("attribute").First().Attribute("value"))).ToList();

With XSLT you can sort the Module children of the Modules element as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Modules">
<xsl:copy>
<xsl:apply-templates select="Module">
<xsl:sort select="Header/setting[#name = 'ModulePosition']/#value" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
http://xsltfiddle.liberty-development.net/948Fn5h
With LINQ and C# you could use
XDocument doc = XDocument.Load("input.xml");
foreach (XElement modules in doc.Descendants("Modules"))
{
modules.ReplaceNodes(
modules
.Elements("Module")
.OrderBy(m => (int)m.Element("Header").Elements("setting").First(s => (string)s.Attribute("name") == "ModulePosition").Attribute("value")).ToList()
);
}
doc.Save("output.xml");

Related

Remove Element from xDocument based on value in repeating segment

In the XML below I am trying to remove the /Bundle/entry/resource/Patient/contained/Patient elements when any of the /Bundle/entry/resource/Patient/contained/Patient/identifier/system value attributes contain "remove-this-Patient" , I could use the full value == "https://example.com/remove-this-Patient" but the "contain" is better for me since the url section can be from multiple places and be slightly different.
I have tried the two code samples below and other variations but none work. The code runs without error but the target Patient element is not removed.
Just as a test I tried using the /Bundle/entry/resource/Patient/contained/Patient/id element in the "where" clause and I was able to get this to work, so I think it has something to do with the /Bundle/entry/resource/Patient/contained/Patient/identifier element being repeating inside the Patient element.
Starting XML
<Bundle>
<id value="xxxx" />
<entry>
<fullUrl value="xxxxxxx" />
<resource>
<Patient>
<id value="xxxx" />
<contained>
<Practitioner>
<id value="xx"/>
</Practitioner>
</contained>
<contained>
<Patient>
<id value="xxxx" />
<identifier>
<type>
<coding>
</coding>
</type>
<system value="http://example.com/remove-this-Patient" />
<value value="xxx" />
</identifier>
<identifier>
<type>
<coding>
</coding>
</type>
<system value="https://example.com/some-other-value" />
<value value="xxx" />
</identifier>
</Patient>
</contained>
<contained>
<Patient>
<id value="xxxx" />
<identifier>
<type>
<coding>
</coding>
</type>
<system value="https://example.com/some-other-thing" />
<value value="xxx" />
</identifier>
<identifier>
<type>
<coding>
</coding>
</type>
<system value="https://example.com/some-other-value" />
<value value="xxx" />
</identifier>
</Patient>
</contained>
</Patient>
</resource>
</entry>
</Bundle>
Desired output would have the /contained/Patient element removed when the child element identifier/system value = "http://example.com/remove-this-Patient"
<Bundle>
<id value="xxxx" />
<entry>
<fullUrl value="xxxxxxx" />
<resource>
<Patient>
<id value="xxxx" />
<contained>
<Practitioner>
<id value="xx"/>
</Practitioner>
</contained>
<contained>
</contained>
<contained>
<Patient>
<id value="xxxx" />
<identifier>
<type>
<coding>
</coding>
</type>
<system value="https://example.com/some-other-thing" />
<value value="xxx" />
</identifier>
<identifier>
<type>
<coding>
</coding>
</type>
<system value="https://example.com/some-other-value" />
<value value="xxx" />
</identifier>
</Patient>
</contained>
</Patient>
</resource>
</entry>
</Bundle>
The two queries below are my attempt to make it work with XDocument, but neither work. They run without error but do not remove the Patient.
xdoc.Root.Descendants("entry").Descendants("resource").Descendants("Patient").Descendants("contained").Descendants("Patient").Where(x => x.Element("identifier").Element("system").Attribute("value").Value.Contains("remove-this-Patient")).Remove();
xdoc.Root.Descendants("entry").Descendants("resource").Descendants("Patient").Descendants("contained").Descendants("Patient").Where(x => (string)x.Descendants("identifier").Where(y=> ("system").Attribute("value")=="https://example.com/remove-this-Patient").Remove();
Please try the following solution based on XSLT transformation.
The XSLT below is following a so called Identity Transform pattern.
The 2nd template removes not needed "/Bundle/entry/resource/Patient/contained/Patient" XML elements based on the presence of the 'remove-this-Patient' value in the #value attribute.
Input XML
<Bundle>
<id value="xxxx"/>
<entry>
<fullUrl value="xxxxxxx"/>
<resource>
<Patient>
<id value="xxxx"/>
<contained>
<Practitioner>
<id value="xx"/>
</Practitioner>
</contained>
<contained>
<Patient>
<id value="xxxx"/>
<identifier>
<type>
<coding>
</coding>
</type>
<system value="http://example.com/remove-this-Patient"/>
<value value="xxx"/>
</identifier>
<identifier>
<type>
<coding>
</coding>
</type>
<system value="https://example.com/some-other-value"/>
<value value="xxx"/>
</identifier>
</Patient>
</contained>
<contained>
<Patient>
<id value="xxxx"/>
<identifier>
<type>
<coding>
</coding>
</type>
<system value="https://example.com/some-other-thing"/>
<value value="xxx"/>
</identifier>
<identifier>
<type>
<coding>
</coding>
</type>
<system value="https://example.com/some-other-value"/>
<value value="xxx"/>
</identifier>
</Patient>
</contained>
</Patient>
</resource>
</entry>
</Bundle>
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Bundle/entry/resource/Patient/contained/Patient[identifier/system[contains(#value, 'remove-this-Patient')]]">
</xsl:template>
</xsl:stylesheet>
Output XML
<Bundle>
<id value="xxxx" />
<entry>
<fullUrl value="xxxxxxx" />
<resource>
<Patient>
<id value="xxxx" />
<contained>
<Practitioner>
<id value="xx" />
</Practitioner>
</contained>
<contained />
<contained>
<Patient>
<id value="xxxx" />
<identifier>
<type>
<coding />
</type>
<system value="https://example.com/some-other-thing" />
<value value="xxx" />
</identifier>
<identifier>
<type>
<coding />
</type>
<system value="https://example.com/some-other-value" />
<value value="xxx" />
</identifier>
</Patient>
</contained>
</Patient>
</resource>
</entry>
</Bundle>
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication5
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
string id = "xxxx";
List<XElement> possibleDeletes = doc.Descendants().Where(x => (x.Element("identifier") != null) && (string)x.Element("id").Attribute("value") == id).ToList();
foreach (XElement possibleDelete in possibleDeletes)
{
List<XElement> identifiers = possibleDelete.Elements("identifier").ToList();
foreach (XElement identifier in identifiers)
{
if (((string)identifier.Element("system").Attribute("value")).Contains("remove")) identifier.Remove();
}
}
}
}
}

Default service descriptions can not be modified as part of upgrade set EnableDefaultServicesUpgrade to true

I am trying to upgrade my Service Fabric application via Visual Studio.
I ended up having to use the diff package approach to ensure that only the services I change are in the upgrade.
I did this via a command file which removed the non-required files.
Now I have walked into another error which is annoying with its lack of detail:
Start-ServiceFabricApplicationUpgrade : Default service descriptions can not be modified as part of upgrade. Modified
2>default service: fabric:/MYAPPLICATION/MYSERVICE. To allow it, set
2>EnableDefaultServicesUpgrade to true.
Where exactly do I put this?
Please note that this is coming from Visual Studio.
I rarely get any joy using PowerShell.
I have seen references to the Update-ServiceFabricService CmdLet, but there is no more information about exactly what I need to do.
I have tried this in the application manifest without success:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="MyServiceFabricApplication.ServiceFabricType" ApplicationTypeVersion="7.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="EnableDefaultServicesUpgrade" DefaultValue="true" />
<Parameter Name="MyParameter" DefaultValue="value" />
Parameters>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServiceFabricApplication.Service1.ServiceFabricPkg" ServiceManifestVersion="4.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="appSettings">
<Parameter Name="MyParameter" Value="[MyParameter]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServiceFabricApplication.Service2.ServiceFabricPkg" ServiceManifestVersion="2.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="appSettings">
<Parameter Name="MyParameter" Value="[MyParameter]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServiceFabricApplication.Service3.ServiceFabricPkg" ServiceManifestVersion="3.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="appSettings">
<Parameter Name="MyParameter" Value="[MyParameter]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServiceFabricApplication.Service4.ServiceFabricPkg" ServiceManifestVersion="2.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="appSettings">
<Parameter Name="MyParameter" Value="[MyParameter]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServiceFabricApplication.PlatformApi.ServiceFabricPkg" ServiceManifestVersion="2.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="appSettings">
<Parameter Name="MyParameter" Value="[MyParameter]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServiceFabricApplication.LivePriceManager.ServiceFabricPkg" ServiceManifestVersion="3.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="appSettings">
<Parameter Name="MyParameter" Value="[MyParameter]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
</ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServiceFabricApplication.Service5.ServiceFabricPkg" ServiceManifestVersion="3.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="appSettings">
<Parameter Name="MyParameter" Value="[MyParameter]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
</ServiceManifestImport>
<DefaultServices>
<Service Name="Service1" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="MyServiceFabricApplication.Service1.ServiceFabricType">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="Service2" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="MyServiceFabricApplication.Service2.ServiceFabricType">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="Service3" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="MyServiceFabricApplication.Service3.ServiceFabricType">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="Service7" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="MyServiceFabricApplication.Service7.ServiceFabricType">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="Service5" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="MyServiceFabricApplication.Service5.ServiceFabricType">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="Service6" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="MyServiceFabricApplication.Service6.ServiceFabricType">
<SingletonPartition />
</StatelessService>
</Service>
<Service Name="Service4" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="MyServiceFabricApplication.Service4.ServiceFabricType">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
</ApplicationManifest>
Paul
First, before I give you a solution, I will give a reason...
EnableDefaultServicesUpgrade is a flag to allow upgrading default services descriptions during application upgrades. When set to true, Default service descriptions are overwritten with new values, this is required to prevent accidental changes to the description that will cause possible failures or dataloss.
When set to false (default), it will make checks to prevent failures to happen,
When set to true, you assume the risk that these changes are safe
An example is when you change the number of partitions in a service and SF predict this will cause dataloss or other failures.
The fix:
EnableDefaultServicesUpgrade is a flag in the cluster definition, not in the service. You have to set this in your cluster manifest.
Your cluster manifest will have a section that looks like this:
...some stuff above...
{
"name": "ClusterManager",
"parameters": [
{
"name": "EnableDefaultServicesUpgrade",
"value": true
}]
... some more stuf below
}
To change it on Azure:
You can use the portal 'http://resources.azure.com' as described in this link
On local cluster:
You copy the clusterconfig.json from the cluster installation folder, apply the changes a trigger a cluster upgrade using the following command Start-ServiceFabricClusterConfigurationUpgrade -ClusterConfigPath .\clusterconfig.json
By the way...
You are using DefaultServices, you should avoid it, there are quite a few questions on SO why.

Combobox ItemsSource using old values from Settings file

I am trying to create a ComboBox and populate the values using Settings file.
In the first attempt it works but when I try to change the values in Settings file, it is not reflected in the list of items in the ComboBox.
Code Snippets for the same -
ComboBox xaml code -
<ComboBox Name="vGameMode"
ItemsSource="{Binding Source={x:Static p:Settings1.Default}, Path=Modes}"
SelectedIndex="1">
<!-- <ComboBoxItem Content="Personal"/>
<ComboBoxItem Content="Corporate"/> -->
</ComboBox>
Values in Settings File -
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="ABC" GeneratedClassName="Settings1">
<Profiles />
<Settings>
<Setting Name="Themes" Type="System.Collections.Specialized.StringCollection" Scope="User">
<Value Profile="(Default)"><?xml version="1.0" encoding="utf-16"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>Theme1</string>
<string>Theme2</string>
<string>Theme3</string>
</ArrayOfString></Value>
</Setting>
<Setting Name="DefaultMaxScore" Type="System.Int32" Scope="User">
<Value Profile="(Default)">1000</Value>
</Setting>
<Setting Name="DefaultTimeoutSeconds" Type="System.Int32" Scope="User">
<Value Profile="(Default)">300</Value>
</Setting>
<Setting Name="LeaderboardDays" Type="System.Int32" Scope="User">
<Value Profile="(Default)">7</Value>
</Setting>
<Setting Name="NumberOfTasks" Type="System.Int32" Scope="User">
<Value Profile="(Default)">3</Value>
</Setting>
<Setting Name="CurrentModeIndex" Type="System.Int32" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
<Setting Name="DifficultyLevels" Type="System.Collections.Specialized.StringCollection" Scope="User">
<Value Profile="(Default)"><?xml version="1.0" encoding="utf-16"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>Medium</string>
<string>Hard</string>
</ArrayOfString></Value>
</Setting>
<Setting Name="GameType" Type="System.Collections.Specialized.StringCollection" Scope="User">
<Value Profile="(Default)"><?xml version="1.0" encoding="utf-16"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>Laser Maze</string>
<string>Laser Buster</string>
</ArrayOfString></Value>
</Setting>
</Settings>
</SettingsFile>
Any idea what is wrong here?
I am guessing it is cached somewhere but not sure where.
Make sure you call Settings1.Default.Save() somewhere in there. I forget that all the time.

Ordering by attribute XML file with nested elements

I would like to order my XML file, but I'm having troubles in understanding how. I noticed that a lot of suggestions are similar to this case.
var bookstore = xDoc.Element("bookstore")
.Elements("book")
.OrderByDescending(s => (int) s.Attribute("id"));
My XML is made like this:
<?xml version="1.0" encoding="utf-8"?>
<rank>
<difficulty template="gamer">
<car type="FormulaA" />
<car type="FormulaC" />
<car type="GT2" />
<car type="FormulaB" />
</difficulty>
<difficulty template="racer">
<car type="FormulaA" />
<car type="FormulaC" />
<car type="GT2" />
<car type="FormulaB" />
</difficulty>
<difficulty template="pro">
<car type="FormulaA" />
<car type="FormulaC" />
<car type="GT2" />
<car type="FormulaB" />
</difficulty>
</rank>
I would like to modify it so that the final result is similar to this one, then write it again to the same file.
<?xml version="1.0" encoding="utf-8"?>
<rank>
<difficulty template="gamer">
<car type="FormulaA" />
<car type="FormulaB" />
<car type="FormulaC" />
<car type="GT2" />
</difficulty>
<difficulty template="racer">
<car type="FormulaA" />
<car type="FormulaB" />
<car type="FormulaC" />
<car type="GT2" />
</difficulty>
<difficulty template="pro">
<car type="FormulaA" />
<car type="FormulaB" />
<car type="FormulaC" />
<car type="GT2" />
</difficulty>
</rank>
I tried to sort those elements with this code, but it doesn't give me the result I want.
XDocument xDoc = XDocument.Load(xmlFile);
var orderedXmlFile = xDoc.Descendants("car").OrderBy(s => (string)s.Attribute("type"));
XDocument doc = new XDocument(new XElement("rank"), orderedXmlFile);
doc.Save(xmlFile);
orderedXmlFile becomes a list similar to
<car type="FormulaA" />
<car type="FormulaA" />
<car type="FormulaA" />
<car type="FormulaB" />
<car type="FormulaB" />
<car type="FormulaB" />
<car type="GT2" />
<car type="GT2" />
<car type="GT2" />
and then I'm unable to save the file. This is the first time I'm trying to modify xml files in C#, so I'll gladly take any advice or suggestions you'd want to give me.
You're not really trying to order all the car elements - you're trying to order each group of elements. It's probably simplest just to use ReplaceNodes for each difficulty element:
foreach (var difficulty in xDoc.Root.Elements("difficulty"))
{
difficulty.ReplaceNodes(difficulty.Elements()
.OrderBy(x => (string) x.Attribute("type")));
}
Then just save xDoc again.
This assumes you don't mind modifying your existing XDocument, of course.

Configuration System Failed To Initialize

In my application when I try to get the connection string by using this code :
System.Configuration.ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString;
It throws an exception that "Configuration System Failed To Initialize". Where is the format of app.config wrong ?
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="ConStr" connectionString="Integrated Security=false;Persist Security Info=False;User ID=funny;password=veryfunny;Initial Catalog=vegimanager;Data Source=.\sqlexpress;"/>
</connectionStrings>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="Vegi_Manager.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
<userSettings>
<Vegi_Manager.Properties.Settings>
<setting name="FIRMNAME" serializeAs="String">
<value/>
</setting>
<setting name="FIRMADDRESS" serializeAs="String">
<value/>
</setting>
<setting name="FIRMCITY" serializeAs="String">
<value/>
</setting>
<setting name="FIRMSTATE" serializeAs="String">
<value/>
</setting>
<setting name="FIRMPHONE" serializeAs="String">
<value/>
</setting>
<setting name="FIRMMOBILE" serializeAs="String">
<value/>
</setting>
<setting name="FIRMEMAIL" serializeAs="String">
<value/>
</setting>
<setting name="FIRMTIN" serializeAs="String">
<value/>
</setting>
<setting name="FIRMPAN" serializeAs="String">
<value/>
</setting>
<setting name="FIRMMANDITAXNO" serializeAs="String">
<value/>
</setting>
<setting name="INITIALFONFIGDONE" serializeAs="String">
<value>False</value>
</setting>
<setting name="FIRMJURISDICTION" serializeAs="String">
<value/>
</setting>
<setting name="FIRMBANKDETAILS" serializeAs="String">
<value/>
</setting>
<setting name="FIRMDETAILS" serializeAs="String">
<value/>
</setting>
<setting name="BILLFORMATNO" serializeAs="String">
<value>0</value>
</setting>
<setting name="PRINTERNAME" serializeAs="String">
<value/>
</setting>
</Vegi_Manager.Properties.Settings>
</userSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
Try putting the configSections as the first child element of configuration, because configSections should be the first element of configurations
So your config file will go like this:
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="Vegi_Manager.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
<connectionStrings>
<add name="ConStr" connectionString="Integrated Security=false;Persist Security Info=False;User ID=funny;password=veryfunny;Initial Catalog=vegimanager;Data Source=.\sqlexpress;"/>
</connectionStrings>
<userSettings>
<Vegi_Manager.Properties.Settings>
<setting name="FIRMNAME" serializeAs="String">
<value/>
</setting>
<setting name="FIRMADDRESS" serializeAs="String">
<value/>
</setting>
<setting name="FIRMCITY" serializeAs="String">
<value/>
</setting>
<setting name="FIRMSTATE" serializeAs="String">
<value/>
</setting>
<setting name="FIRMPHONE" serializeAs="String">
<value/>
</setting>
<setting name="FIRMMOBILE" serializeAs="String">
<value/>
</setting>
<setting name="FIRMEMAIL" serializeAs="String">
<value/>
</setting>
<setting name="FIRMTIN" serializeAs="String">
<value/>
</setting>
<setting name="FIRMPAN" serializeAs="String">
<value/>
</setting>
<setting name="FIRMMANDITAXNO" serializeAs="String">
<value/>
</setting>
<setting name="INITIALFONFIGDONE" serializeAs="String">
<value>False</value>
</setting>
<setting name="FIRMJURISDICTION" serializeAs="String">
<value/>
</setting>
<setting name="FIRMBANKDETAILS" serializeAs="String">
<value/>
</setting>
<setting name="FIRMDETAILS" serializeAs="String">
<value/>
</setting>
<setting name="BILLFORMATNO" serializeAs="String">
<value>0</value>
</setting>
<setting name="PRINTERNAME" serializeAs="String">
<value/>
</setting>
</Vegi_Manager.Properties.Settings>
</userSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
This is a bit late I know but when I remove this:
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
then the error disappears.
This works for me.
Make sure that your app.config or web.config starts with the <configSections> tag inside the <configuration> tab e.g
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true"/>
</configSections>
<connectionStrings>
<add name="ConStr" connectionString="Integrated Security=false;Persist Security Info=False;User ID=funny;password=veryfunny;Initial Catalog=vegimanager;Data Source=.\sqlexpress;"/>
</connectionStrings>
<connectionStrings>
after that make sure that the target Framework property of your project is not client profile

Categories

Resources