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.
Related
I want to remove some tags from an xml. I'm using selectNodes() but I need to pass the namespace. So I tried to get the namespace by using GetXmlNamespaces(). some of the namespaces do not have a key value. And I can not provide the namespace as a hard coded value and need to change the namespace regularly. The only values I can pass are the tag name and the file. Is there anyway I can get the namespace a tag belongs to in c#?
for example I'm passing this namespace as a hardcoded value but I need to do it programmatically.
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("a", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
XmlNodeList nodes = doc.SelectNodes("//a:workbook/a:fileVersion", nsmgr);
this namespace 'xmlns="http://schemas.openxmlformats.org/package/2006/relationships"' does not have a key when I try to get it by using
IDictionary<string, string> nameSpaces = GetXmlNamespaces(xmlFilePath);
Instead of dynamically searching for the used namespace, you can instead find a node without the namespace information.
Have a look at the Q&A's which describe this solution
SelectSingleNode without namespace
Select node without namespace with XPath
How to ignore namespace when selecting XML nodes with XPath
This can be done using localName
refer this question:
Select node without namespace with XPath
Someone had commented this and now it's gone but it worked for me. So here I'm posting the same thing
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();
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.
i need to read the value of a particular value in an xml tag, of he solutions i tried i could only find that to get a value of a tag element ,i need to traverse from root element to the child element.is there an optiion where i can directly select a tag and get its value.
In the below xml exa,i need to get 123456 value from the xml using c#.
Ex:-
<ForwardActionRequest xmlns:auth="test" xmlns="http://www.test">
<auth:Authentication>
<auth:AuthenticationData>
<auth:AuthenticationKey>test</auth:AuthenticationKey>
<auth:Username>test</auth:Username>
<auth:Password>test</auth:Password>
</auth:AuthenticationData>
</auth:Authentication>
<SearchOrderReference>
<Reference>123456</Reference>
<AllocatedBy>test</AllocatedBy>
<Description>test</Description>
</SearchOrderReference>
You can use LINQ to XML:
XDocument doc = XDocument.Load(yourXMLText);
string value = doc.Element("SearchOrderReference").Element("Reference").Value;
Please note that I haven't tested this code.
I also encourage you to read more about LINQ to XML here.
Use XmlDocument.SelectSingleNode() to pass in an XPath that will describe the node you want and then extract the value. Use this prototype as you are using namespaces:
http://msdn.microsoft.com/en-us/library/h0hw012b(v=vs.110).aspx
Read about how to instantiate an XmlNamespaceManager() and initialize it with the relevant prefix (it needs not be what you have in the xml itself), then issue the following request:
XmlNode node = doc.SelectSingleNode("/t:ForwardActionRequest/t:SearchOrderReference/t:Reference");
Given that you associate "t" with "http://www.test".
You can deserialize the xml content into a class and directly get the value of the element or you can use LINQ to XML to retrieve the element value,
XDocument doc=XDocument.Load(XMLContent or XMLPath);
string=doc.Element("SearchOrderReference").Element("Reference").Value;
From your post using VS 2005 you can try the XML Reader which reads the XML from string. Here is an example.
using (XmlReader reader = XmlReader.Create(new StringReader(xml)))
{
reader.ReadToFollowing("SearchOrderReference");
reader.ReadToFollowing("Reference");
string r = reader.ReadInnerXml();
}
Try following code:
XDocument doc = XDocument.Load(yourXMLText);
var node = xmlDoc.SelectSingleNode("//SearchOrderReference[#Reference='123456']");
Then extract node's attribute to get the value of reference tag.
I've got a XmlNodeList which I need to have it in a format that I can then re-use within a XSLT stylesheet by calling it from a C# extension method.
Can anyone help? I have read that it might have something to do with using a XPathNavigator but I'm still a bit stuck.
I had to solve this issue myself a couple of years ago. The only way I managed it was to create an XML fragment containing the nodes in the node list and then passing in the children of the fragment.
XsltArgumentList arguments = new XsltArgumentList();
XmlNodeList nodelist;
XmlDocument nodesFrament = new XmlDocument();
XmlNode root = nodesFragment.CreateElement("root");
foreach (XmlNode node in nodeList)
{
root.AppendChild(node);
}
nodesFragment.AppendChild(root);
arguments.AddParam("argumentname", string.Empty, nodesFragment.CreateNavigator().SelectChildren(XPathNodeType.All));
Then you need to make sure you have the corresponding argument in your XSLT, of course.
Note that you probably don't need the additional XmlDocument. You could just call CreateNavigator() on the root XmlNode instance and use your existing XmlDocument for creating the element (I wrote this code some time ago and I've learned more since then - but I know the code above works, I haven't tried any alternatives).
The note at the end was the most useful, I had infact transformed the XmlNodeList into a XmlDocument already so could just use the Navigator on there and create it as a XPathNodeIterator.
Thanks for you help!
Didn't succeed with the answer provided before.
Using AppendChild() to add previously selected nodes of XmlNodeList to a new document resulted in exception on trying to append nodes originating from a different document context. Several trials to fix this included adding my custom default namespace selected nodes in list are bound to. Finally I dropped the approach completely and switched the way I select nodes into XmlNodeList instances.
Instead of
myXmlNode.SelectNodes( xpath, nsmgr )
I'm using
myXmlNode.CreateNavigator().Select( xpath, nsmgr )
to get an XPathNodeIterator instead of XmlNodeList. The resulting XPathNodeIterator of second code is now properly added as parameter value to XsltArgumentsList.