Re: CFXMLNodeGetString() chokes on "&", "<" or ">"
Re: CFXMLNodeGetString() chokes on "&", "<" or ">"
- Subject: Re: CFXMLNodeGetString() chokes on "&", "<" or ">"
- From: Jerry Krinock <email@hidden>
- Date: Sat, 11 Sep 2004 18:46:25 -0700
I got some time to study this thread further. In the quick example hacked
up by Fred, I note that he actually calls several functions in succession
which "feed" one another:
CFXMLTreeCreateFromData
CFTreeGetChildAtIndex
CFXMLNodeGetString
and then prints the unexpected result. However, I thought, due to "garbage
in, garbage out", this does not prove that CFXMLNodeGetString is the guilty
party. So, I refined his quick hack to systematically parse the entire tree
and print both the type and the string at each node. (Code is in Appendix
2.) I ran it on the same "text.xml" file run by Fred:
<?xml version="1.0" encoding="UTF-8"?>
<foo version="1.0">
<string>you & me</string>
</foo>
and got the following output:
parse ok
type=4, string="xml"
type=2, string="foo"
type=2, string="string"
type=6, string="you "
type=10, string="amp"
type=6, string=" me"
Recalling my earlier conclusion that the unexpected result was caused by
CFXMLNodeGetString choking on the ampersand, it now appears that this
conclusion was incorrect. In fact, the unexpected result is due to
CFXMLTreeCreateFromData breaking up the string "you & me" into three
strings. Fred's example (and my program) access only the first of these
strings; that's why we miss the "& me".
I would much appreciate some opinions from those smarter than me: Is this
behavior from CFXMLTreeCreateFromData expected, or is it a bug???
Jerry Krinock
San Jose, CA USA
***Appendix 1: Those type codes are:
enum CFXMLNodeTypeCode {
...
kCFXMLNodeTypeElement = 2,
...
kCFXMLNodeTypeText = 6,
...
kCFXMLNodeTypeEntityReference = 10,
...
} ;
which is from halfway down this page:
file:///Developer/Documentation/CoreFoundation/Reference/CFXMLNodeRef/index.
html
***Appendix 2: Program which produced the above output:
#include <CoreFoundation/CoreFoundation.h>
void PrintChildrenRecursion(CFXMLTreeRef(curLineage), int depth)
{
int k=0 ;
while (true)
{
CFXMLTreeRef curChild = CFTreeGetChildAtIndex(curLineage, k) ;
if (!curChild)
return ;
// indent output 3 spaces for each level of depth
for (int i=0; i<depth; i++)
printf(" ") ;
CFXMLNodeRef curNode = CFXMLTreeGetNode( curChild ) ;
printf("type=%i, string=\"%s\"\n", CFXMLNodeGetTypeCode(curNode),
[(NSString*)CFXMLNodeGetString(curNode) cString]) ;
PrintChildrenRecursion(curChild, depth+1) ;
k++ ;
}
}
int main(void)
{
CFXMLTreeRef tree;
CFDataRef dat;
CFURLRef u=CFURLCreateWithFileSystemPath(
NULL,CFSTR("test.xml"),
kCFURLPOSIXPathStyle,false);
CFURLCreateDataAndPropertiesFromResource(NULL,
u,&dat,NULL,NULL,NULL);
if(!dat) return 1 ;
tree=CFXMLTreeCreateFromData(NULL,dat,NULL,kCFXMLParserSkipWhitespace,kCFXML
NodeCurrentVersion);
int depth = 0 ;
if(tree)
{
printf("parse ok\n");
PrintChildrenRecursion(tree, depth) ;
}
else printf("no parse\n");
return 0 ;
}
on 04/08/29 16:33, Frederick Cheung at email@hidden wrote:
> On 30 Aug 2004, at 00:22, Jim Correia wrote:
>
>> On Aug 29, 2004, at 4:24 PM, Jerry Krinock wrote:
>>
>>> For example, processing a node which contains the string "you & me"
>>> will return
>>> "you ". Does anyone know why?
>>
>> If your XML really has "you & me" in it, it is invalid. & must be
>> encoded (the same is true for <).
>>
>> <http://www.xml.com/axml/target.html#syntax>
>>
> I don't know what Jerry's doing, but I just tried this out again, and
> it would seem there is a bug.
> I used CFXMLTreeCreateFromData , which as one would expect returns NULL
> if & isn't encoded.
>
> I hacked up this quick example (apologies for horrible code which has
> the structure of my test file hard coded in)
>
> #include <CoreFoundation/CoreFoundation.h>
> int main(void){
> CFXMLTreeRef tree;
> CFDataRef dat;
> CFURLRef u=CFURLCreateWithFileSystemPath(
> NULL,CFSTR("/Users/fred/test.xml"),
> kCFURLPOSIXPathStyle,false);
> CFURLCreateDataAndPropertiesFromResource(NULL,
> u,&dat,NULL,NULL,NULL);
> if(!dat)return;
>
> tree=CFXMLTreeCreateFromData(NULL,dat,NULL,kCFXMLParserSkipWhitespace,kC
> FXMLNodeCurrentVersion);
> if(tree){
> printf("parse ok\n");
> CFXMLTreeRef fooTree=CFTreeGetChildAtIndex(tree,1);
> CFXMLTreeRef string;
> string=CFTreeGetChildAtIndex(fooTree,0);
> CFShow(CFXMLNodeGetString(CFXMLTreeGetNode(
> CFTreeGetChildAtIndex(string,0))));
> }
> else printf("no parse\n");
> }
>
> and ran it against this xml file
> <?xml version="1.0" encoding="UTF-8"?>
> <foo version="1.0">
> <string>you & me</string>
> </foo>
>
> The output is indeed "you" instead of "you & me"
> Sounds like radar time to me.
>
> Fred
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden