Thursday, April 1, 2010

[InDesign CS3] XML Parsing

Hi all,%26lt;br /%26gt;%26lt;br /%26gt;I'm trying to load the content of an XML file(in fact, it麓s an INCX file)in a PMString this way:%26lt;br /%26gt;%26lt;br /%26gt;InterfacePtr%26lt;IPMStream%26gt; sWrite(StreamUtil::CreateFileStreamWrite(fichDest, kOpenOut|kOpenTrunc));%26lt;br /%26gt;if(sWrite == nil)%26lt;br /%26gt;{%26lt;br /%26gt; return kFalse;%26lt;br /%26gt;}%26lt;br /%26gt;PMString pmsXML('''');%26lt;br /%26gt;char *stringTemp;%26lt;br /%26gt;stringTemp= (char*)malloc(tamSrc);%26lt;br /%26gt;while (sRead-%26gt;GetStreamState() != kStreamStateEOF)%26lt;br /%26gt;{%26lt;br /%26gt; memset(cadenaTemp, 0, sizeof(stringTemp));%26lt;br /%26gt; int32 iNum(sRead-%26gt;XferByte((unsigned char *)stringTemp, tamSrc));%26lt;br /%26gt; pmsXML.Append(stringTemp, iNum);%26lt;br /%26gt;}%26lt;br /%26gt;%26lt;br /%26gt;After this, i try to export this PMString (pmsXML) to a file through XferByte this way:%26lt;br /%26gt;%26lt;br /%26gt;PMString ff(''c:\\temp\\test.xml'');%26lt;br /%26gt;IDFile f(ff);%26lt;br /%26gt;InterfacePtr%26lt;IPMStream%26gt; sWrite(StreamUtil::CreateFileStreamWrite(f, kOpenOut|kOpenTrunc));%26lt;br /%26gt;if(sWrite == nil)%26lt;br /%26gt;{%26lt;br /%26gt; return kFalse;%26lt;br /%26gt;}%26lt;br /%26gt;sWrite-%26gt;XferByte((uchar*)pmsXML2.GrabCString(), pmsXML2.ByteLength());%26lt;br /%26gt;sWrite-%26gt;Close();%26lt;br /%26gt;%26lt;br /%26gt;The resultant XML file cannot be opened in the browser and shows the following error:%26lt;br /%26gt;%26lt;br /%26gt;An invalid character was found in text content%26lt;br /%26gt;%26lt;lang pnam=''rk_English: UK'' lsqu=''k_'' ldqu=''k_%26lt;br /%26gt;%26lt;br /%26gt;The XML file has UTF-8 encoding, but has some UNICODE charcaters which provoke this error.%26lt;br /%26gt;%26lt;br /%26gt;The code above worked fine in ID CS2. Does anybody know why it doesn't work now in ID CS3?%26lt;br /%26gt;%26lt;br /%26gt;Regards%26lt;br /%26gt;%26lt;br /%26gt;Alvaro[InDesign CS3] XML Parsing
Please post SDK related questions in the SDK forum.



I do not understand the ''memset'' line.

- what is cadenaTemp ?

- even if it is actually stringTemp where you forgot to find/replace the name, taking the sizeof(stringTemp) is nonsense - sizeof() will yield the size of the pointer rather than the allocated memory ''tamSrc''. If your file is shorter than 4 bytes (sh.. happens), you would even write beyond the allocated buffer.

=%26gt; memset(stringTemp, 0, tamSrc);



Using PMString is asking for trouble if all you intend is to transfer bytes.

PMString is for translatable UI strings.



Your line

pmsXML.Append(stringTemp, iNum);

invokes this overloaded function:

void Append(const PMString %26amp;s, CharCounter nCharacters = kMaxInt32);



therefor a temporary PMString is created for the ''s'' parameter, using this constructor:

PMString(ConstCString key, TranslateDuringCall translate = kDontTranslateDuringCall);



Note that the ''key'' parameter is supposed to be a CString - zero terminated, the zero byte is neither allocated nor initialized in your buffer. In other words, the constructor will either read a random range beyond the buffer or it would crash if we had an ideal memory management.



As for the nature of PMString, probably some conversion is performed during that constructor - e.g. tags interpreted as unicode characters? Just omit the whole intermediate storage in a PMString.



Your code finally broils down to a simple file copy. If that's all you need, have a look at FileUtils.h, it has a function for that purpose:

static bool16 CopyFile(const IDFile%26amp; srcFile, const IDFile%26amp; dstFile);



Dirk
[InDesign CS3] XML Parsing
Hi Dirk,



first of all thanks for your response.



forget the memset line, i agree with you it is unuseful. The code of the previous post was just to show that a simple copy file through a PMString didn`t work. I don`t have to do only a copy file. Once I have the content of the INCA (i wrote INCX by mistake in the previous post) in a PMString I have to apply some changes to that PMString and write again into another file.



That code works perfectly in InDesign CS2 but know in CS3 it doesn't work. I know changes have been apply to PMString and perhaps I cannot use it this way so, what should I use instead to do what I want?



Thanks in advance,



Alvaro.

To work on XML stream, derive from CSAXContentHandler.

Then use the builtin parser:

- in the service registry query for a kXMLParserService / kXMLParserServiceBoss

- set up the appropriate options IID_ISAXPARSEROPTIONS

- let IID_ISAXSERVICES parse the stream into your handler



If the result should be XML again, obtain an IXMLOutStream from IXMLStreamUtils and feed it from within your handler.



Dirk

Thanks Dirk,



I will try it.



Alvaro.

No comments:

Post a Comment