Windows 10 universal XmlNode does not contain a definition for SelectSingleNode - c#

Using Windows 10 Visual Studios C#. I am trying to read from an XML file and I have read through the assembly documentation:
https://msdn.microsoft.com/en-us/library/system.xml.xmlnode(v=vs.110).aspx
The documentation clearly says that 'SelectSingleNode' and 'SelectNodes' are available methods but they don't appear in the predictive list and when trying to use them I get the error message 'XmlNode does not contain a definition for SelectSingleNode'.
I have been searching for a solution to this for a while and I can't seem to find a solution.
(yes, I have included System.Xml and I even tried using the sample code from MS and it produces the same problem)

I am currently running into the same issue, but have started to find some information.
From what I understand about UWP you will need to use XDocument and LINQ, part of the namespace:
System.Xml.Linq
MSDN reference
A code snippet of linq example:
XDocument loadedData = XDocument.Load(XMLPath);
var data = from query in loadedData.Descendants("Order")
select new Countries
{
OrderId = (string)query.Attribute("OrderID") ,
OrderTotal = (string)query.Attribute("OrderTotal"),
Customer = (string)query.Attribute("Customer"),
Phone = (string)query.Attribute("Phone")
};
DataGrid1.ItemsSource = data;
This has been the best solution I have found to the same question.

It is possible you are looking at the System.Xml versions still, which when referenced, do not bring in those methods.
If you rename your System.Xml to Windows.Data.Xml.Dom (namespace), then you won't have XmlNode anymore. It's now IXmlNode. This interface has the SelectSingleNode and SelectNodes you want.

Related

Would schema issues prevent SelectNodes() from finding a node?

I have some very basic XML:
<ReconnectResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://platform.intuit.com/api/v1">
<ErrorMessage/>
<ErrorCode>0</ErrorCode>
<ServerTime>2012-01-04T19:21:21.0782072Z</ServerTime>
<OAuthToken>redacted</OAuthToken>
<OAuthTokenSecret>redacted</OAuthTokenSecret>
</ReconnectResponse>
Simple, right?
So when I want to get the value for ErrorCode, my experience with XPath tells me to try /ReconnectResponse/ErrorCode/text(). This works in Notepad++ equipped with the XML Tools plugin, so lets try it in C#:
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);
var namespaceMan = new XmlNamespaceManager(xmlDoc.NameTable);
Console.WriteLine(xmlDoc.SelectSingleNode(#"/ReconnectResponse/ErrorCode", namespaceMan).InnerText);
I get an exception:
Object reference not set to an instance of an object.
Which smells like a problem finding the specified node. Given how simple the XML is though, I'm struggling to work out what's going wrong.
On a whim, I plopped the XML into XMLQuire. This gives XSD schema errors for each element type, like this:
Could not find schema information for the element 'http://platform.intuit.com/api/v1:ReconnectResponse'.
So, my question is whether or not the schema errors could be causing SelectSingleNode() to miss my nodes? Secondary question: how can I fix it?
You've ignored the namespace of your elements, which in this case is http://platform.intuit.com/api/v1. This is defined by the xmlns=".." attribute in the root element, and all child elements inherit this.
You need to add this namespace to the namespace manager with a prefix:
namespaceMan.AddNamespace("api", "http://platform.intuit.com/api/v1");
And use this prefix in your query:
xmlDoc.SelectSingleNode(#"/api:ReconnectResponse/api:ErrorCode", namespaceMan).InnerText;
As an aside, LINQ to XML is a far cleaner API than XmlDocument and offers much nicer query language than XPath. This code will get you the error code as an integer:
var doc = XDocument.Parse(xmlString);
XNamespace api = "http://platform.intuit.com/api/v1";
var errorCode = (int) doc.Descendants(api + "ErrorCode").Single();

Get node from UrlName in Umbraco

I am working on an Umbraco set up (Umbraco 7) and I need to be able to load a node from a node.UrlName.
I tried Xpath but that didn't work. Here is my xpath:
var facNode = umbraco.NodeFactory.Node.GetNodeByXpath("/*[#UrlName='" + urlName + "']");
I have also tried a few variations of this without /, with // and just looking for an id instead of a UrlName.
This seems to be something fairly simple but I seem to be missing something. I am pretty new to Umbraco so any help would be greatly appreciated.
Id there a better way than xpath? What class should I be using for this?
Thanks in advance!
Well, there are a couple of things here. Firstly, the xpath is case-sensitive, so you need to target #urlName not #UrlName.
Also it's worth pointing out that trying to locate a node by the urlName property isn't a very good strategy because multiple nodes could have an identical urlName property. This is possible because Umbraco only insists that the urlName property is unique where the node shares the same parent.
This makes sense because (e.g. when grouping news/blog articles) you may want a node called October under a node called 2014 but also a node called October under a parent called 2013. In this scenario, your xpath would locate both October nodes and therefore not work.
As far as a btter way, it depends on what the context is and what you are trying to achieve. You certainly should be avoiding using the umbraco.NodeFactory.Node as from Umbraco 4.8 the standard has been to use the IPublishedContent interface which is arguably more flexible.

Select all operations from a wsdl file using xpath

To autogenerate some documentation (and learn xpath) I am tring to get a list of all operations from a WSDL file.
What I have tried so far is:
doc = new XmlDocument();
doc.Load(#"C:\temp\tempuri.org.wsdl");
var list = doc.SelectNodes("wsdl:definitions/wsdl:portType/wsdl:operation");
This gives me the error:
Namespace Manager or XsltContext needed. This query has a prefix,
variable, or user-defined function.
Can anyone explain why I am getting this error and how to fix it?
I'd recommend taking a look at this answer: C# XPath help - Expression not working
You need to register the namespace wsdl before you start querying it.
e.g.:
XPathDocument xDoc = new XPathDocument(#"C:\temp\tempuri.org.wsdl");
XPathNavigator xNav = xDoc.CreateNavigator();
XmlNamespaceManager mngr = new XmlNamespaceManager(xNav.NameTable);
mngr.AddNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/"); // this namespace may need to be different - I don't know what your wsdl file looks like
XPathNodeIterator xIter = xNav.Select("wsdl:definitions/wsdl:portType/wsdl:operation",mngr);
Alternatively you can use LINQ to XML - see this answer from Jon Skeet: Namespace Manager or XsltContext needed
But you said you wanted to learn xPath so I guess it's irrelevant.

Query xml with linq

I am trying to query some informations from xml with linq but I am getting error like this - Yes I have defined - using System.Linq
Could you tell me, where is a problem?
Thanks
Error 1 Could not find an
implementation of the query pattern
for source type
'urn.P.IEEE.Item1671.Item2.Item2008.Item02.InstrumentDescription.InstrumentDescription'.
'Select' not found. D:\Documents and
Settings\e539951\my documents\visual
studio
2010\Projects\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs 28 36 WindowsFormsApplication1
InstrumentDescription test = InstrumentDescription.Load(openFileDialog1.FileName);
var query = from b in test
select new { b.Identification };
In your code test represents just the root element of the document, so you can't use LINQ on it – it's not an sequence.
What you should do depends on how your XSD looks like. For example, if there can be multiple Identification elements under the root InstrumentDescription element, then just accessing test.Identitication gives you the list.
You're handling InstrumentDescription instead of an XDocument so it's probably that you need to make sure you InstrumentDescription class is IQueryable.
If you're actually wanting to do Linq against your XML, you either need to load it in as a dataset, or use Linq2XML (using System.Xml.Linq).
See more here. http://msdn.microsoft.com/en-us/library/system.xml.linq.aspx

xml parsing in C#

Hi Guys
I would like to parse the following xml string in C#
i tried reading the entire string into the dataset and then using it .. there are simply no tables in the dataset.
here is the xml that I am interested to parse.
xml code is here
http://pastebin.com/VfT2wAwY
C# code is here
http://pastebin.com/iwqDK2S6
Thanks and regards,
Gagan Janjua
Have you considered LINQ to XML? If you're using .NET Framework 3.5 or later, then LINQ can save you a lot of time.
I haven't tested this, but you could do something like:
XDocument doc = XDocument.Load(#"C:\mydocument.xml");
var allCases = doc.Element("response").Element("cases").Descendants("case");
foreach (var currentCase in allCases) {
// I can now access each case specifically
var allEvents = currentCase.Descendants("events");
foreach (var currentEvent in allEvents) {
// now I can access each event
int ixBugEvent = (int)currentEvent.Element("ixBugEvent");
// etc...
}
}
Are you aware of XmlReader from System.Xml?
There is no schema in XML that you have provided, so you cannot expect that you can use it to populate DataSet... Unless you define your own schema, that is.
Your code is returning null because of your catch is making it null. It hits the catch, with the following error:
Column name 'ixBugEvent' is defined for different mapping types.
I have the impression that the reason for it is that you have ixBugEvent as both an attribute and a element
<event ixBugEvent='3' ixBug='2'>
<ixBugEvent>3</ixBugEvent>
Removing one of them fix the issue. The code is working, but your xml schema cannot be translated to a dataset.
You can change Scott's code to make it work by changing the following line of code:
// I can now access each case specifically
var allEvents = currentCase.Descendants("events");
Make it:
// I can now access each case specifically
var allEvents = currentCase.Descendants("event");
Doing that you have access to each event element. And from there you can definitely have access to ixBugEvent element.
I hope this helps.
P.s.: Sorry to make this another answer, but I would like to highlight the code, and it seems the only way to do it...

Categories

Resources