How to remove namespace from xml - xpath

I have a XML in following format
<Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<TransactionAcknowledgement xmlns="">
<TransactionId>HELLO </TransactionId>
<UserId>MC</UserId>
<SendingPartyType>SE</SendingPartyType>
</TransactionAcknowledgement>
</Body>
I want to user XQuery or XPath expression for it.
Now I want to remove only
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
namespace from xml.
Is there any way to achieve it.
Thanks

Try to use functx:change-element-ns-deep:
let $xml := <Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<TransactionAcknowledgement xmlns="">
<TransactionId>HELLO </TransactionId>
<UserId>MC</UserId>
<SendingPartyType>SE</SendingPartyType>
</TransactionAcknowledgement>
</Body>
return functx:change-element-ns-deep($xml, "http://schemas.xmlsoap.org/soap/envelope/", "")
But as said Dimitre Novatchev this function doesn't change namespace of the source xml, it creates a new XML.

Related

How to write xpath to checkAddResult value

How to write XPath to get AddResult text value
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<AddResponse xmlns="http://tempuri.org/">
<AddResult>128</AddResult>
</AddResponse>
</soap:Body>
</soap:Envelope>
I tried below but not getting the desired result
declare namespace soap='http://www.w3.org/2003/05/soap-envelope';
/soap:Envelope/soap:Body/AddResponse/AddResult/text()
Found Answeer:
I should create another namespace with url same as in response xml and use in xpath,below is the answer
declare namespace soap='http://www.w3.org/2003/05/soap-envelope';
declare namespace xmlns='http://tempuri.org/';
/soap:Envelope/soap:Body/xmlns:AddResponse/xmlns:AddResult/text()

Decode a xml from std::string with tinyXml

Actually, i have a c++ code which decode a xml from a xml file with TinyXML library.
std::string = "xmlFile.xml";
TiXmlDocument doc(xml_name);
bool loadOkay = doc.LoadFile();
if (loadOkay){...}
Where xmlFile.xml
<?xml version="1.0">
<body>
....
</body>
Now I need to decode the same xml, but now I have the xml contents atfunction input.
I have thought it would be something like:
std::string contents = "<?xml version="1.0"> <body> ... </body>";
TiXmlDocument doc(contents);
bool loadOkay = doc.LoadFile();
if (loadOkay){...}
But obviously, this not work so.
How can I solve this?
Try the TiXmlDocument::Parse() method instead of the LoadFile() method. Also take a look at this question.
Can TinyXml load Xml from string instead of file?

name of node when you know an attribute using path?

I have some XML where I know an attribute (in my case an ID#). I can get the node I'm looking for using //*[#id='v6969482']. But isn't there a way to tell me the name of this id? (I'm trying to have it return 'title' or , in my case. I know it has to do with using name(), but I can't seem to get the right syntax of returning the name when I have the id attribute.
<?xml version="1.0" encoding="UTF-8"?>
<topic id="v6969481">
<title id="v6969482">CR - ASE | AXX2500>Engines>EIOA>EIOAn>GMACn>Ingress</title>
<body id="v6969483">
<p id="v6969484">
<table id="v6153057" frame="all" colsep="1" rowsep="1">
<desc id="v6049915">Global ingress attributes for EIOA engine GMAC ports.</desc>
You need the name of the parent node of the attribute, its parent element:
name(//*[#id='v6969482'])

YQL Losing HTML Element Attributes?

YQL Console Link
Query:
select * from html where url='http://www.cbs.com/shows/big_brother/video/' and xpath='//div[#id="cbs-video-metadata-wrapper"]/div[#class="cbs-video-share"]/a'
Returns:
<?xml version="1.0" encoding="UTF-8"?>
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
yahoo:count="1" yahoo:created="2011-07-09T23:14:02Z" yahoo:lang="en-US">
<diagnostics>
<publiclyCallable>true</publiclyCallable>
<url execution-time="146" proxy="DEFAULT"><![CDATA[http://www.cbs.com/shows/big_brother/video/]]></url>
<user-time>163</user-time>
<service-time>146</service-time>
<build-version>19262</build-version>
</diagnostics>
<results>
<a class="twitter-share-button" href="http://twitter.com/share"/>
</results>
</query>
Should Return Something Similar To:
<results>
</results>
If I back out the query one level, it totally strips out the element, which I could also use to get the data I need.
We have a new html parser that recognizes custom attributes now.
Add compat="html5" to trigger the new parser.
e.g.:
select * from html where url = "http://mydomain.com" and compat="html5"

Problem with namespace and libxml when i use Xpath

i've got a problem when i'm using libxml with XPath. I want to parse an youtube playlist :
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom'
xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'
xmlns:media='http://search.yahoo.com/mrss/'
xmlns:batch='http://schemas.google.com/gdata/batch'
xmlns:yt='http://gdata.youtube.com/schemas/2007'
xmlns:gd='http://schemas.google.com/g/2005'
gd:etag='W/"Dk8DRn47eCp7ImA9WxRQGEk."'>
<id>tag:youtube,2008:user:andyland74:playlists</id>
<updated>2008-07-21T16:43:25.232Z</updated>
<category scheme='http://schemas.google.com/g/2005#kind'
term='http://gdata.youtube.com/schemas/2007#playlistLink'/>
<title>Playlists of andyland74</title>
<logo>http://www.youtube.com/img/pic_youtubelogo_123x63.gif</logo>
<link rel='related' type='application/atom+xml'
href='http://gdata.youtube.com/feeds/api/users/andyland74?v=2'/>
<link rel='alternate' type='text/html'
href='http://www.youtube.com/profile_play_list?user=andyland74'/>
<link rel='http://schemas.google.com/g/2005#feed'
type='application/atom+xml'
href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists?v=2'/>
<link rel='http://schemas.google.com/g/2005#post'
type='application/atom+xml'
href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists?v=2'/>
<link rel='http://schemas.google.com/g/2005#batch'
type='application/atom+xml'
href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists/batch?v=2'/>
<link rel='self' type='application/atom+xml'
href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists?...'/>
<link rel='service' type='application/atomsvc+xml'
href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists?alt=...'/>
<author>
<name>andyland74</name>
<uri>http://gdata.youtube.com/feeds/api/users/andyland74</uri>
</author>
<generator version='2.0'
uri='http://gdata.youtube.com/'>YouTube data API</generator>
<openSearch:totalResults>3</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>25</openSearch:itemsPerPage>
<entry gd:etag='W/"Dk8DRn47eCp7ImA9WxRQGEk."'>
<id>tag:youtube,2008:user:andyland74:playlist:8BCDD04DE8F771B2</id>
<published>2007-11-04T17:30:27.000-08:00</published>
<updated>2008-07-15T12:33:20.000-07:00</updated>
<app:edited xmlns:app='http://www.w3.org/2007/app'>2008-07-15T12:33:20.000-07:00</app:edited>
<category scheme='http://schemas.google.com/g/2005#kind'
term='http://gdata.youtube.com/schemas/2007#playlistLink'/>
<title>My New Playlist Title</title>
<summary>My new playlist Description</summary>
<content type='application/atom+xml;type=feed'
src='http://gdata.youtube.com/feeds/api/playlists/8BCDD04DE8F771B2?v=2'/>
<link rel='related' type='application/atom+xml'
href='http://gdata.youtube.com/feeds/api/users/andyland74?v=2'/>
<link rel='alternate' type='text/html'
href='http://www.youtube.com/view_play_list?p=8BCDD04DE8F771B2'/>
<link rel='self' type='application/atom+xml'
href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists/8BCDD04DE8F771B2?v=2'/>
<link rel='edit' type='application/atom+xml'
href='http://gdata.youtube.com/feeds/api/users/andyland74/playlists/8BCDD04DE8F771B2?v=2'/>
<author>
<name>andyland74</name>
<uri>http://gdata.youtube.com/feeds/api/users/andyland74</uri>
</author>
<yt:countHint>9</yt:countHint>
</entry>
</feed>
when i use the following xpath expression "/feed", the xmlXPathEvalExpression say me that i doesnt find.
if i remove all the xmlns attributes of feed it works. How could i make it work even with xmlns attributes ?
i use libxml with objective-C
I ran into a similar issue when trying to use libxml-ruby to parse through xml. From http://libxml.rubyforge.org/rdoc/classes/LibXML/XML/XPath.html:
To find nodes you must define the atom
namespace for libxml. One way to do
this is:
node = doc.find('atom:title', 'atom:http://www.w3.org/2005/Atom')
Alternatively, you can register the
default namespace like this:
doc.root.namespaces.default_prefix = 'atom' node = doc.find('atom:title')
Either way works, but registering makes sense if you're going to be using the methods a lot. Then you can just reference items like 'atom:title'.
I am using the XPathQuery wrapper around xmlXPathEvalExpression which makes it harder to go the xmlXpathRegisterNS route.
If you are querying for the fields directly, you probably do not care about the namespaces - it doesn't matter for my app. So, I just modified the XML before I process it.
NSString *xmlString = [[NSString alloc] initWithData:originalXMLData encoding:NSUTF8StringEncoding];
NSString *modifiedXMLString = [xmlString stringByReplacingOccurrencesOfString:#"xmlns=" withString:#"foobar="];
NSData *modifiedXMLData = [modifiedXMLString dataUsingEncoding:NSUTF8StringEncoding];
Now you can use modifiedXMLData in xmlXPathEvalExpression or PerformXMLXPathQuery if you use XPathQuery.
You didn't post your query code, but it sounds like you aren't registering the namespaces with your XpathContext. Here's the API docs for xmlXPathRegisterNS, I believe it will do what you're looking for. It won't let you register a default namespace, so you'll need to change your XPath expression to /feed:feed or the like.
To use a default namespace just register the namespace xlmns= and then use /xmlns:feed in your query.
After some research, I found the following solution that just works like NSXMLDocument path queries:
when xml documents declare a default namespace without a prefix, like
xmlns="..."
simple xpaths queries fail, like
xpath: /node
that's because xmlXPathEvalExpressionexpects some kind of default namespace prefix but there is none.
One approach is to fix the missing prefix (like GDataXML does) but that requires all xpaths to use this prefix, like
xpath: /__def_ns:node
But this is not how xpath's and NSXMLDocument works.
The following solution (based on a DDXMLNode) goes to the root node and scans for a namesepace without a prefix.
Then all nodes below are being traversed and if they belong to that namespace, it is being removed.
This is just like if there was no namespace in the first place.
- (void)fixNameSpace
{
xmlNodePtr nodePtr = (xmlNodePtr)self->genericPtr;
xmlNsPtr ns = nodePtr->nsDef;
xmlNsPtr defaultNs = NULL;
while(ns != NULL)
{
if (ns->prefix == NULL)
{
defaultNs = ns;
break;
}
ns = ns->next;
}
if (defaultNs)
[self resetDefaultNs:defaultNs];
}
- (void)resetDefaultNs:(xmlNsPtr)defaultNs
{
xmlNodePtr nodePtr = (xmlNodePtr)self->genericPtr;
xmlNsPtr ns = nodePtr->ns;
if (ns && ns == defaultNs)
xmlSetNs(nodePtr, NULL);
for (NSXMLNode* child in self.children)
[child resetDefaultNs:defaultNs];
}

Resources