Discussion:
Creating a DOM Document from HTTP Request of XML failing
Cris R
2010-04-06 04:54:29 UTC
Permalink
Hi,

I send an HTTP Request, which returns the following XML.

<?xml version="1.0" encoding="UTF-8"?>
<users_getInfo_response xmlns="http://api.facebook.com/1.0/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://api.facebook.com/1.0/
http://api.facebook.com/1.0/facebook.xsd" list="true">
<user>
<about_me xsi:nil="true"/>
<first_name>Chewy</first_name>
<last_name>Cat</last_name>
<uid>100000495237103</uid>
<pic_square>http://profile.ak.fbcdn.net/v22944/850/83/q10000049523710
3_4003.jpg</pic_square>
</user>
</users_getInfo_response>


To parse the XML, my understanding is I should create a document. (Is
such correct?)
So to create a DOMDocument, I have the following C++ code:

nsCOMPtr<nsIDOMDocument> document;
rv = inXMLHttpRequest->GetResponseXML(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
<rest of my code>

rv does not get an error. eg rv is set to NS_OK, but the raw pointer
of document, ends up being null, and the NS_ENSURE_TRUE exits my
routine, so the <rest of my code> does not execute.

Why is this happening? Is my XML not proper? Any thoughts?

Thanks in advance,

-cris
Boris Zbarsky
2010-04-06 13:41:41 UTC
Permalink
Post by Cris R
rv does not get an error. eg rv is set to NS_OK, but the raw pointer
of document, ends up being null, and the NS_ENSURE_TRUE exits my
routine, so the<rest of my code> does not execute.
Why is this happening? Is my XML not proper? Any thoughts?
Are you calling this GetResponseXML code _after_ the XHR completes?

-Boris
Cris R
2010-04-06 15:26:18 UTC
Permalink
Post by Boris Zbarsky
Post by Cris R
rv does not get an error. eg rv is set to NS_OK, but the raw pointer
of document, ends up being null, and the NS_ENSURE_TRUE exits my
routine, so the<rest of my code> does not execute.
Why is this happening? Is my XML not proper? Any thoughts?
Are you calling this GetResponseXML code _after_ the XHR completes?
Yes, The XML output posted earlier was from the same call, outputting the text of the
inXMLHttpRequest->GetResponseText(text);


eg full code is:

nsAutoString response;
rv = inXMLHttpRequest->GetResponseText(response);
NS_ENSURE_SUCCESS(rv, rv);

const char* debugOutput = NS_ConvertUTF16toUTF8(response ).get();
MyDebugLog(debugOutput );

nsCOMPtr<nsIDOMDocument> document;
rv = inXMLHttpRequest->GetResponseXML(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);

-cris
Boris Zbarsky
2010-04-06 15:32:28 UTC
Permalink
Post by Cris R
Yes, The XML output posted earlier was from the same call, outputting the text of the
inXMLHttpRequest->GetResponseText(text);
OK. In that case, is the data actually being served as XML? What HTTP
headers does the server send?

-Boris
Cris
2010-04-06 16:01:00 UTC
Permalink
No headers. That XML was the entire output. I'm guessing this is the
problem.

-cris

Sent from my iPhone
Post by Boris Zbarsky
Post by Cris R
Yes, The XML output posted earlier was from the same call,
outputting the text of the
inXMLHttpRequest->GetResponseText(text);
OK. In that case, is the data actually being served as XML? What
HTTP headers does the server send?
-Boris
_______________________________________________
dev-tech-dom mailing list
https://lists.mozilla.org/listinfo/dev-tech-dom
Boris Zbarsky
2010-04-06 16:05:47 UTC
Permalink
Post by Cris
No headers. That XML was the entire output. I'm guessing this is the
problem.
Yep. Either the server needs to claim the output is XML or you need to
tell your XHR to treat the data as XML no matter what the server says.

-Boris
Cris Rys
2010-04-12 06:44:09 UTC
Permalink
Post by Cris
No headers. That XML was the entire output. I'm guessing this is the
problem.
Yep. Either the server needs to claim the output is XML or you need to tell
your XHR to treat the data as XML no matter what the server says.
-Boris
Thank you Boris. I am successfully able to create the Document.

Walking through the document, I am able to GetTagName, successfully, eg I get "first_name", "last_name", "uid", as tag names, but when call element->GetAttribute("value") I get an empty string result. Should I not be querying the element's value? What should I be doing?


The XML code is below, and the C++ code that is causing the error is below.

Thanks,

-cris
-------


<?xml version="1.0" encoding="UTF-8"?>
<users_getInfo_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/facebook.xsd" list="true">
<user>
<about_me xsi:nil="true"/>
<first_name>Cris</first_name>
<last_name>Rys</last_name>
<uid>693893361</uid>
</user>
</users_getInfo_response>

-------

nsCOMPtr<nsIDOMDocument> document;
rv = inXMLHttpRequest->GetResponseXML(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);

nsCOMPtr<nsIDOMNodeList> userNodeList;
rv = document->GetElementsByTagName(NS_LITERAL_STRING("user"), getter_AddRefs(userNodeList));
NS_ENSURE_STATE(userNodeList);
NS_ENSURE_SUCCESS(rv, rv);

PRUint32 userNodeListLength = 0;
rv = userNodeList->GetLength(&userNodeListLength);
NS_ENSURE_SUCCESS(rv, rv);

nsCOMPtr<nsIDOMNode> userNode;
rv = userNodeList->Item(0, getter_AddRefs(userNode));
NS_ENSURE_SUCCESS(rv, rv);

nsCOMPtr<nsIDOMNodeList> childNodes;
rv = userNode->GetChildNodes(getter_AddRefs(childNodes));
NS_ENSURE_SUCCESS(rv, rv);

PRUint32 childNodeListLength = 0;
rv = childNodes->GetLength(&childNodeListLength);
NS_ENSURE_SUCCESS(rv, rv);

nsString first_name, last_name, pic_square,profile_url, uidStr;
uint64_t uid = 0;

for(PRUint32 i = 0; i < childNodeListLength; ++i)
{
nsCOMPtr<nsIDOMNode> domNode;
rv = childNodes->Item(i, getter_AddRefs(domNode));
NS_ENSURE_SUCCESS(rv, rv);

nsCOMPtr<nsIDOMElement> element = do_QueryInterface(domNode, &rv);
if(NS_FAILED(rv))
{
continue;
}

nsString tagName;
rv = element->GetTagName(tagName); // successfully gets names of "first_name", "last_name", "uid"
NS_ENSURE_SUCCESS(rv, rv);

nsString value;
rv = element->GetAttribute(NS_LITERAL_STRING("value"), value); // but attribute value is an empty string
if(NS_FAILED(rv))
{
continue;
}

if(tagName.EqualsLiteral("first_name"))
{
first_name = value;
}
else if(tagName.EqualsLiteral("last_name"))
{
last_name = value;
}
else if(tagName.EqualsLiteral("uid"))
{
uidStr = value;
}

}
Cris Rys
2010-04-12 08:02:03 UTC
Permalink
To answer my own question, looking at the attribute value was incorrect. Getting the interface for a nsIDOM3Node which I could call GetTextContent on was what I needed to do. -cris


nsCOMPtr<nsIDOM3Node> dom3Node = do_QueryInterface(element, &rv);
NS_ENSURE_SUCCESS(rv, rv);

nsString textContent;
rv = dom3Node->GetTextContent(textContent);
NS_ENSURE_SUCCESS(rv, rv);
Post by Cris Rys
Post by Cris
No headers. That XML was the entire output. I'm guessing this is the
problem.
Yep. Either the server needs to claim the output is XML or you need to tell
your XHR to treat the data as XML no matter what the server says.
-Boris
Thank you Boris. I am successfully able to create the Document.
Walking through the document, I am able to GetTagName, successfully, eg I get "first_name", "last_name", "uid", as tag names, but when call element->GetAttribute("value") I get an empty string result. Should I not be querying the element's value? What should I be doing?
The XML code is below, and the C++ code that is causing the error is below.
Thanks,
-cris
-------
<?xml version="1.0" encoding="UTF-8"?>
<users_getInfo_response xmlns="http://api.facebook.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.facebook.com/1.0/facebook.xsd" list="true">
<user>
<about_me xsi:nil="true"/>
<first_name>Cris</first_name>
<last_name>Rys</last_name>
<uid>693893361</uid>
</user>
</users_getInfo_response>
-------
nsCOMPtr<nsIDOMDocument> document;
rv = inXMLHttpRequest->GetResponseXML(getter_AddRefs(document));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMNodeList> userNodeList;
rv = document->GetElementsByTagName(NS_LITERAL_STRING("user"), getter_AddRefs(userNodeList));
NS_ENSURE_STATE(userNodeList);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 userNodeListLength = 0;
rv = userNodeList->GetLength(&userNodeListLength);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> userNode;
rv = userNodeList->Item(0, getter_AddRefs(userNode));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNodeList> childNodes;
rv = userNode->GetChildNodes(getter_AddRefs(childNodes));
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 childNodeListLength = 0;
rv = childNodes->GetLength(&childNodeListLength);
NS_ENSURE_SUCCESS(rv, rv);
nsString first_name, last_name, pic_square,profile_url, uidStr;
uint64_t uid = 0;
for(PRUint32 i = 0; i < childNodeListLength; ++i)
{
nsCOMPtr<nsIDOMNode> domNode;
rv = childNodes->Item(i, getter_AddRefs(domNode));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(domNode, &rv);
if(NS_FAILED(rv))
{
continue;
}
nsString tagName;
rv = element->GetTagName(tagName); // successfully gets names of "first_name", "last_name", "uid"
NS_ENSURE_SUCCESS(rv, rv);
nsString value;
rv = element->GetAttribute(NS_LITERAL_STRING("value"), value); // but attribute value is an empty string
if(NS_FAILED(rv))
{
continue;
}
if(tagName.EqualsLiteral("first_name"))
{
first_name = value;
}
else if(tagName.EqualsLiteral("last_name"))
{
last_name = value;
}
else if(tagName.EqualsLiteral("uid"))
{
uidStr = value;
}
}
Loading...