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.
Related
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();
}
}
}
}
}
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.
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");
I am developping a windows 8.1 application and since few days I am struggling with a problem.
Here is my probem:
I have a tfs project and via my application I want to follow it (displaying the state, created by, changed by,etc) using tfs odata.
Here is the xml file obtained :
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="https://tfsodata.visualstudio.com/DefaultCollection/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title type="text">WorkItems</title>
<id>https://tfsodata.visualstudio.com/DefaultCollection/Projects('project1')/WorkItems/</id>
<updated>2014-05-02T14:52:17Z</updated>
<link rel="self" title="WorkItems" href="WorkItems" />
<entry m:etag="W/"datetime'2014-03-12T19%3A54%3A38.193%2B00%3A00'"">
<id>https://tfsodata.visualstudio.com/DefaultCollection/WorkItems(1)</id>
<title type="text">ProjetTest</title>
<summary type="text"></summary>
<updated>2014-03-12T19:54:38Z</updated>
<author>
<name />
</author>
<link rel="edit" title="WorkItem" href="WorkItems(1)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Attachments" type="application/atom+xml;type=feed" title="Attachments" href="WorkItems(1)/Attachments" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Links" type="application/atom+xml;type=feed" title="Links" href="WorkItems(1)/Links" />
<category term="Microsoft.Samples.DPE.ODataTFS.Model.Entities.WorkItem" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:Id m:type="Edm.Int32">1</d:Id>
<d:Project>project1</d:Project>
<d:Type>Product Backlog Item</d:Type>
<d:WebEditorUrl>https://xxxx.visualstudio.com/web/wi.aspx?pcguid=f2ba9200-f167-43e8-a92e-d36b1bc1b561&id=1</d:WebEditorUrl>
<d:AreaPath>ptoject1</d:AreaPath>
<d:IterationPath>project1</d:IterationPath>
<d:Revision m:type="Edm.Int32">2</d:Revision>
<d:Priority m:null="true" />
<d:Severity m:null="true" />
<d:StackRank m:type="Edm.Double">0</d:StackRank>
<d:AssignedTo></d:AssignedTo>
<d:CreatedDate m:type="Edm.DateTime">2014-03-12T19:54:25.783+00:00</d:CreatedDate>
<d:CreatedBy>xxxxx</d:CreatedBy>
<d:ChangedDate m:type="Edm.DateTime">2014-03-12T19:54:38.193+00:00</d:ChangedDate>
<d:ChangedBy>xxxxx</d:ChangedBy>
<d:ResolvedBy m:null="true" />
<d:Title>ProjetTest</d:Title>
<d:State>New</d:State>
<d:Reason>New backlog item</d:Reason>
<d:CompletedWork m:type="Edm.Double">0</d:CompletedWork>
<d:RemainingWork m:type="Edm.Double">0</d:RemainingWork>
<d:Description></d:Description>
<d:ReproSteps m:null="true" />
<d:FoundInBuild m:null="true" />
<d:IntegratedInBuild></d:IntegratedInBuild>
<d:AttachedFileCount m:type="Edm.Int32">0</d:AttachedFileCount>
<d:HyperLinkCount m:type="Edm.Int32">0</d:HyperLinkCount>
<d:RelatedLinkCount m:type="Edm.Int32">0</d:RelatedLinkCount>
<d:Risk m:null="true" />
<d:StoryPoints m:type="Edm.Double">0</d:StoryPoints>
<d:OriginalEstimate m:type="Edm.Double">0</d:OriginalEstimate>
<d:BacklogPriority m:type="Edm.Double">1000000000</d:BacklogPriority>
<d:BusinessValue m:type="Edm.Int32">0</d:BusinessValue>
<d:Effort m:type="Edm.Double">0</d:Effort>
<d:Blocked m:null="true" />
<d:Size m:type="Edm.Double">0</d:Size>
</m:properties>
</content>
</entry>
<entry m:etag="W/"datetime'2014-03-24T12%3A07%3A56.397%2B00%3A00'"">
<id>https://tfsodata.visualstudio.com/DefaultCollection/WorkItems(2)</id>
<title type="text">test2</title>
<summary type="text"></summary>
<updated>2014-03-24T12:07:56Z</updated>
<author>
<name />
</author>
<link rel="edit" title="WorkItem" href="WorkItems(2)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Attachments" type="application/atom+xml;type=feed" title="Attachments" href="WorkItems(2)/Attachments" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Links" type="application/atom+xml;type=feed" title="Links" href="WorkItems(2)/Links" />
<category term="Microsoft.Samples.DPE.ODataTFS.Model.Entities.WorkItem" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:Id m:type="Edm.Int32">2</d:Id>
<d:Project>project1</d:Project>
<d:Type>Product Backlog Item</d:Type>
<d:WebEditorUrl>https://xxxxx.visualstudio.com/web/wi.aspx?pcguid=f2ba9200-f167-43e8-a92e-d36b1bc1b561&id=2</d:WebEditorUrl>
<d:AreaPath>project1</d:AreaPath>
<d:IterationPath>project1</d:IterationPath>
<d:Revision m:type="Edm.Int32">4</d:Revision>
<d:Priority m:null="true" />
<d:Severity m:null="true" />
<d:StackRank m:type="Edm.Double">0</d:StackRank>
<d:AssignedTo></d:AssignedTo>
<d:CreatedDate m:type="Edm.DateTime">2014-03-12T20:16:49.827+00:00</d:CreatedDate>
<d:CreatedBy>xxxx</d:CreatedBy>
<d:ChangedDate m:type="Edm.DateTime">2014-03-24T12:07:56.397+00:00</d:ChangedDate>
<d:ChangedBy>xxxx</d:ChangedBy>
<d:ResolvedBy m:null="true" />
<d:Title>test2</d:Title>
<d:State>Committed</d:State>
<d:Reason>Additional work found</d:Reason>
<d:CompletedWork m:type="Edm.Double">0</d:CompletedWork>
<d:RemainingWork m:type="Edm.Double">0</d:RemainingWork>
<d:Description></d:Description>
<d:ReproSteps m:null="true" />
<d:FoundInBuild m:null="true" />
<d:IntegratedInBuild></d:IntegratedInBuild>
<d:AttachedFileCount m:type="Edm.Int32">0</d:AttachedFileCount>
<d:HyperLinkCount m:type="Edm.Int32">0</d:HyperLinkCount>
<d:RelatedLinkCount m:type="Edm.Int32">0</d:RelatedLinkCount>
<d:Risk m:null="true" />
<d:StoryPoints m:type="Edm.Double">0</d:StoryPoints>
<d:OriginalEstimate m:type="Edm.Double">0</d:OriginalEstimate>
<d:BacklogPriority m:type="Edm.Double">999968378</d:BacklogPriority>
<d:BusinessValue m:type="Edm.Int32">0</d:BusinessValue>
<d:Effort m:type="Edm.Double">0</d:Effort>
<d:Blocked m:null="true" />
<d:Size m:type="Edm.Double">0</d:Size>
</m:properties>
</content>
</entry>
</feed>
my class:
paste special as xml classes (from the xml above)
my function :
public IEnumerable<TfsEntitiesXml.feed> Deserialize()
{
string xml = "https://tfsodata.visualstudio.com/DefaultCollection/Projects('xxxx')/WorkItems".Trim();
XmlSerializer serilaizer = new XmlSerializer(typeof(TfsEntitiesXml.feed));
//string xml = "";
byte[] buffer = Encoding.UTF8.GetBytes(xml);
var stream = new MemoryStream();
stream.WriteAsync(buffer, 0, buffer.Length);
IEnumerable<TfsEntitiesXml.feed> result = (IEnumerable<TfsEntitiesXml.feed>)serilaizer.Deserialize(stream);
return result;
}
and the xaml
<ListView x:Name="itemsListView"
SelectionMode="None"
ItemsSource="{Binding TfsList}" >
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock
Foreground=
"{StaticResource ListViewItemOverlayForegroundThemeBrush}"
Style="{StaticResource TitleTextStyle}" Height="60"
TextWrapping="Wrap"
Margin="15,5,15,0">
<Run Text="{Binding Title}" ></Run>
<Run Text="{Binding State}" ></Run>
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
var projects = tfsConnector.Deserialize();
DefaultViewModel["TfsList"] = projects;
When I run I get this exception
An exception of type 'System.InvalidOperationException' occurred in System.Xml.dll but was not handled in user code
Additional information: There is an error in XML document (0, 0).
I am struggling with this problem since few days now.
Can someone help me please?
Thank you
You should simply make a service reference to the tfsodata service, this way you will get a typed reference and don't have to mess with the xml.
See this blogpost
I would like to construct a Hierarchical TreeView in WPF from an available XML data.This Data could be Dynamic so Tree may end up having many levels of children. My sample XML looks like this:
<Groups>
<Group Name="Global" ID="1">
<Group Name="Demo - Marketing" ID="2" />
<Group Name="Demo - Finance" ID="3" />
<Group Name="Demo - Operations" ID="4" />
<Group Name="Demo - Sandpit" ID="5" />
<Group Name="Morson" ID="6">
<Group Name="Internal" ID="29">
<Group Name="Branch" ID="31">
<Group Name="Branch Components WIP" ID="50" />
<Group Name="MI32_IT Recruitment" ID="51" />
<Group Name="Branch Master" ID="52" />
<Group Name="Branch Master_Perm" ID="76" />
<Group Name="MI42_Manchester Rail Technical" ID="79" />
<Group Name="MI39_London Technical" ID="86" />
<Group Name="MI51_Oil & Gas London" ID="87" />
<Group Name="MI40_London Support Services" ID="88" />
<Group Name="MI28_Manchester Rail" ID="119" />
<Group Name="MI35_Heathrow" ID="125" />
<Group Name="MI73_London Telco" ID="150" />
<Group Name="MI04_EPB" ID="158" />
</Group>
<Group Name="Consultant" ID="32">
<Group Name="Consultant Master " ID="53" />
<Group Name="MI32_SBS_Steven Byrne" ID="57" />
<Group Name="MI32_RH_Robert Hoffman" ID="58" />
<Group Name="MI32_J3D_Jonathan Darbyshire" ID="60" />
<Group Name="MI32_BS_Bobby Sethi" ID="61" />
<Group Name="MI32_DM_Diana Mathers" ID="62" />
<Group Name="MI32_KER_Kerry Redmond" ID="63" />
<Group Name="MI32_MO_Marc Oldland" ID="65" />
</Group>
<Group Name="Director" ID="33">
<Group Name="Director_Client Internal" ID="320" />
<Group Name="Director_Client External" ID="321" />
<Group Name="Director_Net Starters_Finishers" ID="400" />
<Group Name="Director AWR" ID="455" />
<Group Name="Director Board Data_Gareth Owen" ID="488" />
</Group>
<Group Name="Finance" ID="36">
<Group Name="Fin_Net Starters_Finishers" ID="401" />
<Group Name="Fin_Turnover (Unadjusted)" ID="464" />
<Group Name="Fin_Systems Spend" ID="487" />
<Group Name="Fin_Sales Ledger" ID="504" />
</Group>
<Group Name="System Administration" ID="44" />
<Group Name="Account Manager" ID="68">
<Group Name="Account Manager Master" ID="69" />
<Group Name="URS" ID="70" />
<Group Name="Chubb" ID="71" />
<Group Name="Welsh Water" ID="72" />
<Group Name="Thales" ID="74" />
<Group Name="Costain" ID="75" />
<Group Name="Airbus" ID="124" />
</Group>
<Group Name="Branch Administration" ID="330">
<Group Name="MI39_Admin_London Technical" ID="331" />
<Group Name="Branch Administration Master" ID="351" />
<Group Name="MI19_Admin_Science" ID="363" />
<Group Name="MI51_Admin_Oil & Gas London" ID="364" />
<Group Name="MI02_Admin_Aerospace_Preston" ID="367" />
<Group Name="MI02_Admin_Aerospace_South" ID="471" />
<Group Name="MI02_Admin_Aerospace_South_Nicola Leggett" ID="485" />
<Group Name="MO01_Admin_Houston" ID="495" />
</Group>
<Group Name="Payroll" ID="414" />
<Group Name="Business Development" ID="454" />
<Group Name="JC - Work In Progress (JDV)" ID="503" />
<Group Name="JC - Work In Progress (Vencuro)" ID="507" />
<Group Name="Sales Ledger View - Work in Progress" ID="512" />
<Group Name="JC - Work In Progress (Thales)" ID="543" />
</Group>
<Group Name="External" ID="30">
<Group Name="Client" ID="34">
<Group Name="Client Master" ID="54" />
<Group Name="Costain" ID="73" />
</Group>
</Group>
<Group Name="Demo Dashboards" ID="47" />
<Group Name="Master Components" ID="416" />
<Group Name="Demo Designer" ID="531" />
</Group>
</Group>
</Groups>
How can I achieve A treeview with Group Names in hierarchical manner? sample XAML and Class to bind Items would be really helpful. - Programming Language C#
Many thanks in advance.
-Vinnie
First you need to create your class from XML schema like this:
[XmlRoot("Groups")]
public class GroupsXml
{
[XmlElement("Group", typeof(Group))]
public List<Group> GroupsList { get; set; }
}
public class Group
{
[XmlAttribute("ID")]
public int Id { get; set; }
[XmlAttribute("Name")]
public string Name{ get; set; }
}
Then you need to serialize your xml string into list of objects or groups in your case for example:
public List<Group> ReadGroupsFromXmlFile(string fileName)
{
var groupsXml = new GroupsXml();
var groupsXmlFile = xDocument.Load(fileName).ToString();
var groupType = groupsXml .GetType();
var oXmlSerializer = new XmlSerializer(groupType);
groupsXml = (GroupsXml)oXmlSerializer.Deserialize(new StringReader(groupsXmlFile ));
return categoriesXml.GroupsList;
}
I hope it answers your question