Microsoft Developer Network >
Página Inicial dos Fóruns
>
.NET Base Class Library
>
xml selectsinglenode
xml selectsinglenode
- Hello,
I have this xml
I would like to select the SessionID node. I thought the syntax was would be<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header/> <soapenv:Body> <SessionID xmlns="http://www.niku.com/xog">11938473__567b131:124c40c66bc:-7f361257534325686</SessionID> </soapenv:Body> </soapenv:Envelope>
Can someone please help me with the syntax.Dim xmlDoc As New XmlDocument xmlDoc.LoadXml(xml) Dim node As XmlNode = xmlDoc.SelectSingleNode("descendant::SessionID")
Thank you,
Respostas
- Sorry again, I totally misunderstood your problem a couple of times. I think you are having problems with the fact that XPath does not support anonymous namespaces. You put SessionID into an anonymous namespace with the xmlns="http://www.niky.com/xog" namespace attribute. In your query, use an XmlNamespaceManager to assign an actual name to that namespace, and use that name in your XPath. The name can be anything. Here, I will provide an example, giving the anonymous namespace the name foo .
class Program { static void Main( string[] args ) { string xml = @"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> <soapenv:Header/> <soapenv:Body> <SessionID xmlns='http://www.niku.com/xog'>11938473__567b131:124c40c66bc:-7f361257534325686</SessionID> </soapenv:Body> </soapenv:Envelope>"; XmlDocument doc = new XmlDocument(); doc.LoadXml( xml ); XmlNamespaceManager nsmgr = new XmlNamespaceManager( doc.NameTable ); nsmgr.AddNamespace( "foo", "http://www.niku.com/xog" ); XmlNode node = doc.SelectSingleNode( "descendant::foo:SessionID", nsmgr ); Console.WriteLine( node.Name ); } }
Hopefully now I'm on the same page as you!
Note that your xpath syntax has changed from
descendant::SessionID
to
descendant::foo:SessionID
Note the use of a double colon for axis specifier and single colon for namespace separator.- Marcado como RespostaRohrer segunda-feira, 9 de novembro de 2009 16:42
Todas as Respostas
- Sorry...
Try "//SessionID"
or "/*/*/SessionID"
- EditadoWyck sexta-feira, 6 de novembro de 2009 19:37misunderstood
- How to query XML with an XPath expression by using Visual C#:
http://support.microsoft.com/default.aspx/kb/308333
XPathNavigator Class
Provides a cursor model for navigating and editing XML data:
http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathnavigator.aspx
XPathNavigator Select Method (XPathExpression)
http://msdn.microsoft.com/en-us/library/3tk3f03k.aspx
The following example uses the Select method to select a node set.
Dim document As XPathDocument = New XPathDocument("books.xml") Dim navigator As XPathNavigator = document.CreateNavigator() Dim query As XPathExpression = navigator.Compile("/bookstore/book") Dim nodes As XPathNodeIterator = navigator.Select(query) Dim nodesNavigator As XPathNavigator = nodes.Current Dim nodesText As XPathNodeIterator = nodesNavigator.SelectDescendants(XPathNodeType.Text, False) While nodesText.MoveNext() Console.WriteLine(nodesText.Current.Value) End While
XPathDocument document = new XPathDocument("books.xml"); XPathNavigator navigator = document.CreateNavigator(); XPathExpression query = navigator.Compile("/bookstore/book"); XPathNodeIterator nodes = navigator.Select(query); XPathNavigator nodesNavigator = nodes.Current; XPathNodeIterator nodesText = nodesNavigator.SelectDescendants(XPathNodeType.Text, false); while (nodesText.MoveNext()) { Console.WriteLine(nodesText.Current.Value); }
- I am confused about this. I haven't ever had to use xpathnavigator to select nodes.
This is a example of the xml I am dealing with:
When I run the following code:<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header/> <soapenv:Body> <ReadTimeperiodResponse xmlns="http://www.niku.com/xog/Object"> <NikuDataBus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/nikuxog_timeperiod.xsd"> <Header externalSource="NIKU" version="8.1.4.4573"/> <TimePeriods/> <XOGOutput> <Object type="timeperiod"/> <Status state="SUCCESS"/> <Statistics failureRecords="0" insertedRecords="0" totalNumberOfRecords="0" updatedRecords="0"/> <Records/> <DeprecationInformation> <Severity>WARNING</Severity> <Description>DEPRECATION MESSAGE</Description> <Exception type="java.lang.Exception">The action and objectType attributes in the Header have been deprecated.</Exception> </DeprecationInformation> </XOGOutput> </NikuDataBus> </ReadTimeperiodResponse> </soapenv:Body> </soapenv:Envelope>
Dim doc As New XmlDocument
doc.LoadXml(responseText)
Dim testList As XmlNodeList = doc.SelectNodes("//*")
It finds the following xml elements:
soapenv:Envelope
soapenv:Header
soapenv:Body
ReadTimeperiodResponse
NikuDataBus
Header
TimePeriods
XOGOutput
Object
Status
Statistics
Records
DeprecationInformation
Severity
Description
Exception
If you look at the list, you can see that XOGOutput is in the list.
Now if I run this following code:
Dim doc As New XmlDocument
doc.LoadXml(responseText)
Dim testList As XmlNodeList = doc.SelectNodes("//XOGOutput/*")
I get no results. Which makes no sense to me, because it should find any elements with the name of XOGOutput. It should return 1 element.
Any help would be appreciated.
Thank you
- Hi,
Actually
Dim testList As XmlNodeList = doc.SelectNodes("//XOGOutput/*")
should return
Object
Status
Statistics
Records
DeprecationInformation
Since you are selecting the sub nodes of XOGOutput (the /* means all nodes at the level below the previous node which is XOGOutput).
I'm not sure, but I think the zero result might be caused by multiple namespaces in the xml. You might have to use a System.Xml.XmlNamespaceManager with the SelectNodes method, but I'm not entirely sure how to set it up correctly. - I believe that is part of the problem.
When I check doc.NameSpaceURI, it is string.empty. The doc.NameTable is also empty, which means the xml doesn't have any namespaces.
Why would this occur? If you view the xml, it clearly has namespaces.
- I'm afraid I don't know, most Xml I work with doesn't have namespaces so I haven't encountered this before.
I suspect that while the Xml has namespaces embedded in it, that doesn't automatically cause the objects you're reading to fetch the schema's/map the namespaces etc. and that you are still required to either set them up manually, or start some process to tell the system it's ok to do those things. - LINQ is another good option for you.
Short method:
instantiate XDocument.
Use XDocument.Parse(<Your XML String>);
var sessiond= from myXml in <Your XDocument created aboe> select myXml.Element("SessionID").Value;
Querying XML in C# with LINQ to XML:
http://www.microsoft.com/uk/msdn/nuggets/nugget/204/querying-xml-in-c-with-linq-to-xml.aspx
Regards,
Jai - I would love to use linq, except currently we are only supporting 2.0. :(
- Sorry again, I totally misunderstood your problem a couple of times. I think you are having problems with the fact that XPath does not support anonymous namespaces. You put SessionID into an anonymous namespace with the xmlns="http://www.niky.com/xog" namespace attribute. In your query, use an XmlNamespaceManager to assign an actual name to that namespace, and use that name in your XPath. The name can be anything. Here, I will provide an example, giving the anonymous namespace the name foo .
class Program { static void Main( string[] args ) { string xml = @"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> <soapenv:Header/> <soapenv:Body> <SessionID xmlns='http://www.niku.com/xog'>11938473__567b131:124c40c66bc:-7f361257534325686</SessionID> </soapenv:Body> </soapenv:Envelope>"; XmlDocument doc = new XmlDocument(); doc.LoadXml( xml ); XmlNamespaceManager nsmgr = new XmlNamespaceManager( doc.NameTable ); nsmgr.AddNamespace( "foo", "http://www.niku.com/xog" ); XmlNode node = doc.SelectSingleNode( "descendant::foo:SessionID", nsmgr ); Console.WriteLine( node.Name ); } }
Hopefully now I'm on the same page as you!
Note that your xpath syntax has changed from
descendant::SessionID
to
descendant::foo:SessionID
Note the use of a double colon for axis specifier and single colon for namespace separator.- Marcado como RespostaRohrer segunda-feira, 9 de novembro de 2009 16:42

