I have a problem, I am trying to list all my tfs projects and I am having this exception:
Value does not fall within the expected range.
Here is my method
public async Task<XElement> Deserialize()
{
string xml = "https://tfsodata.visualstudio.com/DefaultCollection/Projects('xxxx')/WorkItems";
var feed = await this.GetAsync(PROJECTS_PATH);
var x = feed.Items.ToString();
XElement dataTfs = new XElement(x);
foreach(var tfsdata in feed.Items)
{
var xDoc = XDocument.Parse(tfsdata.Content.Text);
IEnumerable<XElement> elem = xDoc.Elements();
XNamespace m = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
var data = from query in xDoc.Descendants(m + "properties")
select new TfsEntities.Models.TfsEntities.properties
{
Title = (string)query.Element(d + "Title"),
State = (string)query.Element(d + "State"),
Reason = (string)query.Element(d + "Reason")
};
dataTfs.Add(data.ToList());
}
return (XElement)dataTfs;
}
Does anyone know how to fix this problem please?
Thank you
Related
I have a Xamarin (C#) project, where I am trying to loop through some XML, but for some reason my code is not working.
This is what I have now:
DeviceList = new List<DeviceInfo>();
string ResultStatus = "";
string ResultDevice = "";
var result = Encoding.Default.GetString(e.Result);
result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + result;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(result);
string xPathStatus = "ed_listdevices";
var nodes = xmlDoc.SelectNodes(xPathStatus);
foreach (XmlNode xNode in nodes) {
ResultStatus = xNode.SelectSingleNode("//status").InnerText;
ResultDevice = xNode.SelectSingleNode("//device").InnerText;
}
if (ResultStatus.ToLower() == "ok") {
XmlDocument deviceDoc = new XmlDocument();
deviceDoc.LoadXml(result);
var deviceNodes = deviceDoc.SelectNodes(xPathStatus + "/device");
//foreach(XmlNode dNode in deviceNodes) {
for (int i = 0; i < deviceNodes.Count; i++) {
DeviceList.Add(new DeviceInfo() {
DeviceID = deviceNodes[i].SelectSingleNode("//id").InnerXml,
DeviceName = deviceNodes[i].SelectSingleNode("//name").InnerXml,
DeviceExtraName = "",
DeviceOnlineStatus = deviceNodes[i].SelectSingleNode("//status").InnerXml,
Location = deviceNodes[i].SelectSingleNode("//address").InnerXml,
Time = deviceNodes[i].SelectSingleNode("//time").InnerXml
});
}
}
When I step though the code I get the "ResultStatus" and "ResultDevice" correctly, and when I get to the
for (int i = 0; i < deviceNodes.Count; i++)
the "deviceNodes" variable have a count of 91, and I can see all the individual xml elements that I am suppose to get from the webservice I am calling.
However, when I loop through deviceNodes[i] I only get values from the very first XML element (yes, the value of "i" does change). In other words, my DeviceList is filled with 91 entries with the same values.
Am I missing something obvious?? What am I doing wrong since this isn't working??
PS: I have also tried using a foreach (XmlNode node in deviceNodes) but the result was the same.
"//" in the selector tells it to search from the root node of the document. If you want to search locally under the "current" node, remove the "//"
i want to sort the nodes called ImageInfo by the number in the pos node because i have buttons that change the position up or down and i need to sort the ImageInfo node in the correct order when the pos has changed.
i apologise ahead for not having any c# code but i assure you that i have tried so many different things and im in need of help.
here is my xml:
<?xml version="1.0" encoding="utf-8"?>
<MplAndSiImages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MplImages>
<ImageInfo>
<pos>1</pos>
<Name>1.png</Name>
<ParentObjectId>b66a23a8-6268-e611-80e2-c4346bad02e8</ParentObjectId>
<Url>http://localhost:8080/b66a23a8-6268-e611-80e2-c4346bad02e8/1.png</Url>
</ImageInfo>
<ImageInfo>
<pos>2</pos>
<Name>2.png</Name>
<ParentObjectId>b66a23a8-6268-e611-80e2-c4346bad02e8</ParentObjectId>
<Url>http://localhost:8080/b66a23a8-6268-e611-80e2-c4346bad02e8/2.png</Url>
</ImageInfo>
<ImageInfo>
<pos>3</pos>
<Name>3.png</Name>
<ParentObjectId>b66a23a8-6268-e611-80e2-c4346bad02e8</ParentObjectId>
<Url>http://localhost:8080/b66a23a8-6268-e611-80e2-c4346bad02e8/3.png</Url>
</ImageInfo>
</MplImages>
<SiImages />
</MplAndSiImages>
here is my c# code:
it is called on the click of an action link button and i need it to change the poition to 1 less to move it up in the list and i have the number change but the xml need s to be sorted so it has the ImageInfo nodes in the correct order.
public ActionResult MoveUp(string name, string id)
{
var pathConfig = WebConfigurationManager.AppSettings["ProductImageFolderPath"];
var url = pathConfig + id + "\\" + "ModelConfig.xml";
XmlDocument doc = new XmlDocument();
doc.Load(url);
XmlNode root = doc.DocumentElement;
XmlNode upNode = root.SelectSingleNode("/MplAndSiImages/MplImages/ImageInfo[Name/text() = '" + name + "']/pos");
string upNodeValue = upNode.InnerText;
int upNodeInt = Int32.Parse(upNodeValue);
upNodeInt = upNodeInt - 1;
var upNodeString = upNodeInt.ToString();
upNode.InnerText = upNodeString;
XmlNode downNode = root.SelectSingleNode("/MplAndSiImages/MplImages/ImageInfo/pos[text() = '" + upNodeString + "']");
string downNodeValue = downNode.InnerText;
int downNodeInt = Int32.Parse(downNodeValue);
downNodeInt = downNodeInt + 1;
var downNodeString = downNodeInt.ToString();
downNode.InnerText = downNodeString;
Func<string, int> ParseIntOrDefault = (string input) =>
{
int output;
int.TryParse(input, out output);
return output;
};
var result = doc.SelectNodes("MplAndSiImages/MplImages/*")
.Cast<XmlNode>()
.OrderBy(element => element.SelectSingleNode("pos").InnerText)
.ToList();
doc.Save(url);
return RedirectToAction("UploadAnImage", new { id = id });
}
I have seen this and tried it but is there any way of doing this with xmldocument:
XElement root = XElement.Load(xmlfile);
var orderedtabs = root.Elements("Tab")
.OrderBy(xtab => (int)xtab.Element("Order"))
.ToArray();
root.RemoveAll();
foreach(XElement tab in orderedtabs)
root.Add(tab);
root.Save(xmlfile);
I am ordering the images to display on a web page.
and when the move up button is pressed the image will be moved up in the list and swap places with the image above it.
Using linq to xml you can:
var result = XDocument.Load("data.xml")
.Descendants("ImageInfo")
.OrderBy(element => element.Element("pos")?.Value)
.ToList();
And in order to order it by the int value of it you can:
Func<string,int> ParseIntOrDefault = (string input) =>
{
int output;
int.TryParse(input, out output);
return output;
};
var result = XDocument.Load("data.xml")
.Descendants("ImageInfo")
.OrderBy(element => ParseIntOrDefault(element.Element("pos")?.Value))
.ToList();
Using XmlDocument to read the xml you can:
var doc = new XmlDocument();
doc.Load("data.xml");
var result = doc.SelectNodes("MplAndSiImages/MplImages/*")
.Cast<XmlNode>()
.OrderBy(element => element.SelectSingleNode("pos").InnerText)
.ToList();
Here too you can use the ParseIntOrDefault from above
I want to extract the field yt:username from this XML:
var xDoc = XDocument.Load(requestedURL);
var m_oListaMeteo = xDoc.Descendants(ns + "entry").Select(n =>
{
return new
{
username = n.Element(ns + "yt:username").Value
};
});
but XDocument itself says The ':' character, hexadecimal value 0x3A, cannot be included in a name.
A string replace is needed? Or need I to manage namespace of youtube?
yt is namespace, Try this:
var xDoc = XDocument.Load(#"https://gdata.youtube.com/feeds/api/users/djfonplaz/subscriptions?v=2");
var ns = XNamespace.Get("http://www.w3.org/2005/Atom");
var yt = XNamespace.Get("http://gdata.youtube.com/schemas/2007");
var m_oListaMeteo = xDoc.Descendants(ns + "entry").Select(n =>
{
return new
{
username = n.Element(yt + "username").Value
};
});
Make sure you are using the proper namespaces:
var xDoc = XDocument.Load(requestedURL);
var m_oListaMeteo = xDoc
.Root
.Elements("{http://www.w3.org/2005/Atom}entry")
.Select(entry => new
{
username = entry.Element("{http://gdata.youtube.com/schemas/2007}username").Value
});
How would I go about getting the ID information using Linq. I'm trying to add them to an array of int.
<FactionAttributes>
<name>Player</name>
<id>0</id>
<relationModifier>1</relationModifier>
<relations>
<id0>100</id0>
<id1>50</id1>
<id2>50</id2>
<id3>50</id3>
<id4>50</id4>
<id5>50</id5>
</relations>
</FactionAttributes>
That is my XML.
Here is the code I'm using so far.
void InitFactions()
{
int count = 0;
string filepath = Application.dataPath + "/Resources/factiondata.xml";
XDocument factionXML = XDocument.Load(filepath);
var factionNames = from factionName in factionXML.Root.Elements("FactionAttributes")
select new {
factionName_XML = (string)factionName.Element("name"),
factionID_XML = (int)factionName.Element("id"),
factionRelations_XML = factionName.Element("relations")// Need to turn this into array.
};
foreach ( var factionName in factionNames)
++count;
foreach ( var factionName in factionNames)
{
Factions f = new Factions();
f.otherFactionsName = new string[count];
f.otherFactionsRelation = new int[count];
int others = 0;
f.FactionName = factionName.factionName_XML;
Debug.Log(factionName.factionRelations_XML);
// Adds Rivals, not self to other list.
foreach (var factionName2 in factionNames)
{
if (factionName.factionID_XML == factionName2.factionID_XML)
continue;
f.otherFactionsName[(int)factionName2.factionID_XML] = factionName2.factionName_XML;
// THIS IS WHERE IM ADDING THE RELATIONS IN //
f.otherFactionsRelation[(int)factionName2.factionID_XML] = factionName.factionRelations_XML[(int)factionName2.factionID_XML];
Debug.Log(f.FactionName + " adds: " + factionName2.factionName_XML);
++others;
}
}
}
I have made multiple attempts using nodes and what not. I can't seem to figure out the correct syntax.
XDocument doc = XDocument.Load(Path);
//To get <id>
var MyIds = doc.Element("FactionAttributes").Element("id").Value;
//To get <id0>, <id1>, etc.
var result = doc.Element("FactionAttributes")
.Element("relations")
.Elements()
.Where(E => E.Name.ToString().Contains("id"))
.Select(E => new { IdName = E.Name, Value = E.Value});
If you want array of ints replace the select with this
.Select(E => Convert.ToInt32(E.Value)).ToArray();
If you are just after the relations Ids use this simple query
var doc = XDocument.Load("c:\\tmp\\test.xml");
var ids = doc.Descendants("relations").Elements().Select(x => x.Value);
If you want the Id and the relations ids in one array use this
var id = doc.Descendants("id").Select(x=>x.Value).Concat(doc.Descendants("relations").Elements().Select(x => x.Value));
My goal is to save the data contained in the ValueReference node, TimeInstant attribute, and timePosition node into variables. I am able to get the value of the valueReference node (the un-commented section works), but not the other two.
Any help would be greatly appreciated.
Here is the code that I am working on:
public void LinqToXml()
{
XNamespace sosNamespace = XNamespace.Get("http://www.opengis.net/sos/2.0");
XNamespace fesNamespace = XNamespace.Get("http://www.opengis.net/fes/2.0");
XNamespace gmlNamespace = XNamespace.Get("http://www.opengis.net/gml/2.0");
var root = XElement.Load(#"C:\Working Directory\OGCSOS.Service\OGCSOS.Service\Resources\GetObservation_TemporalFilter.xml");
var a = (from level in root.Descendants(sosNamespace + "temporalFilter")
select new
{
valueReference = (string)level.Descendants(fesNamespace + "After")
.Elements(fesNamespace + "ValueReference")
.First(),
/*timeInstant = (string)level.Descendants(fesNamespace + "After")
.Elements(gmlNamespace + "TimeInstant")
.Attributes(gmlNamespace + "id")
.First()*/
/*timePosition = (string)level.Descendants(fesNamespace + "After")
.Elements(gmlNamespace + "TimeInstant")
.First()*/
}).ToList();
And here is the XML I am trying to read:
<?xml version="1.0" encoding="UTF-8"?>
<sos:GetObservation xmlns="http://www.opengis.net/sos/2.0" service="SOS" version="2.0.0"
xmlns:sos="http://www.opengis.net/sos/2.0" xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:swe="http://www.opengis.net/swe/2.0"
xmlns:swes="http://www.opengis.net/swes/2.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/sos/2.0
http://schemas.opengis.net/sos/2.0/sos.xsd">
<!--identifier of an offering-->
<offering>HG.Logger#DJK001</offering>
<!--identifier of an observed property-->
<observedProperty>HG</observedProperty>
<!--optional temporal filter restricting the results which shall be returned-->
<temporalFilter>
<fes:After>
<fes:ValueReference>phenomenonTime</fes:ValueReference>
<gml:TimeInstant gml:id="startPosition">
<gml:timePosition>2008-03-01T17:44:15.000+00:00</gml:timePosition>
</gml:TimeInstant>
</fes:After>
</temporalFilter>
<featureOfInterest>DJK001</featureOfInterest>
</sos:GetObservation>
Your gml namespace is not correct, after changing it to
XNamespace gmlNamespace = XNamespace.Get("http://www.opengis.net/gml/3.2");
you can use
timeInstant = level.Descendants(fesNamespace + "After")
.First()
.Element(gmlNamespace + "TimeInstant")
.Attribute(gmlNamespace + "id")
.Value,
timePosition = level.Descendants(fesNamespace + "After")
.First()
.Element(gmlNamespace + "TimeInstant")
.Value
You should do it like this
XNamespace sosNamespace = "http://www.opengis.net/sos/2.0";
XNamespace fesNamespace = "http://www.opengis.net/fes/2.0";
XNamespace gmlNamespace = "http://www.opengis.net/gml/3.2";
//you had used 2.0 instead of 3.2
var root = XElement.Load(#"C:\WorkingDirectory\OGCSOS.Service\OGCSOS.Service\Resources\GetObservation_TemporalFilter.xml");
var yourList=root.Descendants(sosNamespace+"temporalFilter").Descendants(fesNamespace+"After").Select(x=>
new
{
ValueReference=x.Element(fesNamespace+"ValueReference").Value,
timeInstant=x.Element(gmlNamespace+"TimeInstant").Attribute(gmlNamespace+"id").Value,
timePosition=x.Element(gmlNamespace+"TimeInstant").Element(gmlNamespace+"timePosition").Value
}
);
yourList contains all the data
you can also use good old XPath
var doc = new XPathDocument("1.xml");
var nav = doc.CreateNavigator();
var mng = new XmlNamespaceManager(nav.NameTable);
mng.AddNamespace("sos", "http://www.opengis.net/sos/2.0");
mng.AddNamespace("fes", "http://www.opengis.net/fes/2.0");
mng.AddNamespace("gml", "http://www.opengis.net/gml/3.2");
var valueReference = nav.SelectSingleNode("//sos:GetObservation/sos:temporalFilter/fes:After/fes:ValueReference[1]", mng).TypedValue;
var TimeInstant = nav.SelectSingleNode("//sos:GetObservation/sos:temporalFilter/fes:After/gml:TimeInstant/#gml:id", mng).TypedValue;
var timePosition = nav.SelectSingleNode("//sos:GetObservation/sos:temporalFilter/fes:After/gml:TimeInstant/gml:timePosition[1]", mng).TypedValue;
TRY THIS CODE:
XmlDocument xmlSnippet = new XmlDocument();
xmlSnippet.Load(#"C:\Working Directory\OGCSOS.Service\OGCSOS.Service\Resources\GetObservation_TemporalFilter.xml");
//Selects all the similar nodes by tag Name.......
XmlNodeList xmlSnippetNodes = xmlSnippet.GetElementsByTagName("fes:After");
//Checking if any any xmlSnippetNode has matched.
if (xmlSnippetNodes != null)
{
//Checks if the matched xmlSnippetNode that has fes:After attribute is not NULL
//Stores the value of the matched tag.
var valueReference= xmlSnippetNodes.Item(0).Value;
var timeInstance=xmlSnippetNodes.Item(1).Attributes["gml:id"].Value;
var timePosition =xmlSnippetNodes.Item(1).InnerXml.Name;
//Return True if updated correctly.
isUpdated = true;
}