newbie question about xml

J

JustSomeGuy

When you have an xml message and you want to extract a particular
item, what is the normal search method?

Say you have:

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:GetExternalIPAddressResponse
xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">
<NewExternalIPAddress>
168.46.10.14
</NewExternalIPAddress>
</u:GetExternalIPAddressResponse>
</s:Body>
</s:Envelope>


So if you are interested in the 168.46.10.14

Do you specify that you want:
s:Envelope.s:Body.u:GetExternalIPAddressResponse.NewExternalIPAddress

or simply:

NewExternalIPAddress

Does this make sence?
 
W

William Park

JustSomeGuy said:
When you have an xml message and you want to extract a particular
item, what is the normal search method?

Say you have:

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:GetExternalIPAddressResponse
xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">
<NewExternalIPAddress>
168.46.10.14
</NewExternalIPAddress>
</u:GetExternalIPAddressResponse>
</s:Body>
</s:Envelope>


So if you are interested in the 168.46.10.14

Do you specify that you want:
s:Envelope.s:Body.u:GetExternalIPAddressResponse.NewExternalIPAddress

or simply:

NewExternalIPAddress

Does this make sence?

There are many way to extract that data:
- regex
- XML parser (eg. Expat)
- XSL
Choose your pick.
 
J

JustSomeGuy

William Park said:
There are many way to extract that data:
- regex
- XML parser (eg. Expat)
- XSL
Choose your pick.

I'm not talking about 'tool-kits'...
My question is more 'procedurally' oriented.
 
A

Andy Dingley

When you have an xml message and you want to extract a particular
item, what is the normal search method?

You need to be more careful with your terminology, or you'll get
bitten in the future. (but if you're asking this question, it shows
you're at least thinking about the right stuff).

You're using some complex technology here. You have XML, SOAP, then
some application on top of that. Now if you do it right, all this stuf
fis your friend - an XML tool handles the XML for you, an app server
takes care of SOAP, and some little EJB knows how to sort out the
application level stuff. If you mix it all up though, things get
awkward - you'll find yourself trying to write what should be a very
simple bean that knows about the
schemas-upnp-org:service:WANIPConnection stuff, but instead you've
coded all sorts of SOAP related stuff into it. If you don't
appreciate _why_ this is bad, go and look up the terms "coherence and
coupling".


You could write any bit of XPath in here, and it would extract your
data

/s:Envelope/s:Body/u:GetExternalIPAddressResponse/u:NewExternalIPAddress/text()
would do it. However that's Bad Coding.


Anything with
/s:Envelope/s:Body/*
in it is bad. That's coupling the SOAP envelope and body together,
and that's a no-no for SOAP. You're supposed to be able to pass
bodies around independently, passing them between different envelopes
as SOAP does some routing for you. OK, so it doesn't happen much, but
it _might_.


Anything with
//s:*//u:*
in it is bad. That's coupling SOAP and the u namespace (the
application protocol) together. Why should your u-specific EJB know
anything about SOAP ? Why should it be coded so that it can _only_
work with messages arriving from a SOAP source ?

I've seen this piece of code _so_ many times 8-(
I've even seen some idiots wrap faked-up SOAP bodies around the data
payload, to work around their broken code. These people should be in
marketing.


The right XPath is something like
u:GetExternalIPAddressResponse/u:NewExternalIPAddress/text()
You'll note that this doesn't work !

To get it to work, you need to pass it a starting context that's the
content of s:Body. This is good practice (if you're using some sort
of pre-written framework for implementing SOAP, it'll probably do this
for you). The advantage is that your own EJB (or whatever) is now
independent of SOAP and doesn't care _where_ your
<u:GetExternalIPAddressResponse> element came from.



//u:NewExternalIPAddress/text()
_might_ work, but I'd advise against it. Can you guarantee that this
will always be the right element ? What would happen if the body
started containing it as a child of some other element as well, like
this?
 
J

JustSomeGuy

Andy Dingley said:
You need to be more careful with your terminology, or you'll get
bitten in the future. (but if you're asking this question, it shows
you're at least thinking about the right stuff).
Ok what is the 'correct' terminology? Lest the gods of xml smite me.

You're using some complex technology here. You have XML, SOAP, then
some application on top of that. Now if you do it right, all this stuf
fis your friend - an XML tool handles the XML for you, an app server
takes care of SOAP, and some little EJB knows how to sort out the
application level stuff. If you mix it all up though, things get
awkward - you'll find yourself trying to write what should be a very
simple bean that knows about the
schemas-upnp-org:service:WANIPConnection stuff, but instead you've
coded all sorts of SOAP related stuff into it. If you don't
appreciate _why_ this is bad, go and look up the terms "coherence and
coupling".

My application has classes for soap and html and for xml.
Sorry whats an EJB (A Java Bean?).. You must excuse me I'm a c++ guy.

You could write any bit of XPath in here, and it would extract your
data

XPath eh.. Ok So this string of text is a 'normal' way of requesting
the text your looking for?

/s:Envelope/s:Body/u:GetExternalIPAddressResponse/u:NewExternalIPAddress/tex
t()
would do it. However that's Bad Coding.
Ok thank you I'll keep that in mind.
Anything with
/s:Envelope/s:Body/*
in it is bad. That's coupling the SOAP envelope and body together,
and that's a no-no for SOAP. You're supposed to be able to pass
bodies around independently, passing them between different envelopes
as SOAP does some routing for you. OK, so it doesn't happen much, but
it _might_.


Anything with
//s:*//u:*
in it is bad. That's coupling SOAP and the u namespace (the
application protocol) together. Why should your u-specific EJB know
anything about SOAP ? Why should it be coded so that it can _only_
work with messages arriving from a SOAP source ?

I see your point.
I've seen this piece of code _so_ many times 8-(
I've even seen some idiots wrap faked-up SOAP bodies around the data
payload, to work around their broken code. These people should be in
marketing.

I wish I were... I'd be making more money! ;)
The right XPath is something like
u:GetExternalIPAddressResponse/u:NewExternalIPAddress/text()
You'll note that this doesn't work !

To get it to work, you need to pass it a starting context that's the
content of s:Body. This is good practice (if you're using some sort
of pre-written framework for implementing SOAP, it'll probably do this
for you). The advantage is that your own EJB (or whatever) is now
independent of SOAP and doesn't care _where_ your
<u:GetExternalIPAddressResponse> element came from.



//u:NewExternalIPAddress/text()
_might_ work, but I'd advise against it. Can you guarantee that this
will always be the right element ? What would happen if the body
started containing it as a child of some other element as well, like
this?

Thanks for a great reply.
This was the exact question I had on my mind as well.. What if its not
the right element... Well I suppose that that means that Microsoft changed
the interface to their InternetGatewayDevice specification... (Something
microsoft would never consider doing ;) Then of course I'd be forced to
change the software. I am assuming that no matter what interface you are
dealing with you need to know the interface in order to deal with it.
Very much like dealing with a c++ class... when a member function changes
then so must the software that called it. Or have I missed the point?

My next question of course is about the namespaces 'u' and 's'. These
were the namespace I defined when I made the original request so I assume
the server preserved it for me?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top