XML file handling help

Discussion in 'Mac Programming' started by A@ron, Feb 20, 2007.

  1. macrumors member

    Joined:
    May 2, 2002
    Location:
    Iowa
    #1
    First off, thank you to anyone that can help I am really just a cocoa novice on a mission to write something useful :)

    Background:
    I am working on a preference pane front end to TivoMono which simply can put files on my tivo and transcode them on the fly for it.
    I only need this preferance pane to really perform 4 different functions:
    1) start the terminal process with mono Tivomono.exe --nodetails --noterminal Done
    2) be able to stop the process Done uses pkill and works
    3) read the settings.xml that TivoMono.exe reads to configure itself and set the gui buttons/drop downs to reflect the current settings.

    XML File Example
    Code:
    <TiVoMono>
      <Installpath>/TivoMono/</Installpath>
      <FFMpeg_Path>/TivoMono/ffmpeg</FFMpeg_Path>
      <FFMpeg_Aspect>4:3</FFMpeg_Aspect>
      <FFMpeg_VideoBitRate>2048</FFMpeg_VideoBitRate>
      <FFMpeg_FrameRate>24</FFMpeg_FrameRate>
      <FFMpeg_AudioBitRate>128</FFMpeg_AudioBitRate>
      <FFMpeg_AudioSampleRate>48000</FFMpeg_AudioSampleRate>
      <FFMpeg_RestrictAudioSampleRate>false</FFMpeg_RestrictAudioSampleRate>
      <FFMpeg_AudioCodec>mp2</FFMpeg_AudioCodec>
      <FFMpeg_AudioChannels>2</FFMpeg_AudioChannels>
      <FFMpeg_RestrictAudioChannels>true</FFMpeg_RestrictAudioChannels>
      <FFMpeg_AudioSyncSamples>1</FFMpeg_AudioSyncSamples>
      <FFMpeg_UseAsync>false</FFMpeg_UseAsync>
      <Directory>/Volumes/HD2/TiVoNet/</Directory>
      <AllowedExtensions>.3g2,.3gp,.4xm,.mtv,.roq,.aac,.ac3,.adts,.aiff,.alaw,.amr,.asf,.au,.avi,.avs,.crc,.daud,.dsicin,.dts,.dv,.dvd,.ea,.ffm,.flic,.flv,.gif,.gxf,.h261,.h263,.h264,.idcin,.ipmovie,.m4v,.matroska,.mjpeg,.mm,.mmf,.mov,.mp4,.m4a,.3gp,.mp2,.mp3,.mp4,.mpeg,.mpeg1video,.mpeg2video,.mpegts,.mpegvideo,.mpjpeg,.mulaw,.mxf,.nsv,.nuv,.ogg,.psp,.psxstr,.rawvideo,.rm,.s16be,.s16le,.s8,.shn,.smk,.sol,.svcd,.swf,.tiertexseq,.tta,.u16be,.u16le,.u8,.vcd,.vmd,.vob,.voc,.wav,.wc3movie,.wsaud,.wsvqa,.wv,.mpg</AllowedExtensions>
      <UUID>190C7D52-C6F8-4D3C-A5FE-3D1710DFB898</UUID>
    </TiVoMono>
    4) If a save settings button is pressed then the preference pane needs to remake the settings.xml and replace the old one, kill the process and restart it.

    What I need help with:
    I am having a heck of a time opening this XML file properly and getting it to do what it needs to do. If anyone could get me pointed in the right direction that would be greatly appreciated. I've tried to read up on NSXML but examples are lacking unfortunately.

    Here is my code so far if it helps:
    homepage.mac.com/bedelman/TivoPref.zip

    Thank you!
     
  2. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #2
    I'm too lazy to look through your project.. mind putting the XML sample code up? If the XML isn't valid, NSXMLDocument will return nil and an error.
     
  3. thread starter macrumors member

    Joined:
    May 2, 2002
    Location:
    Iowa
    #3
    Code:
    	NSXMLDocument *settingsXML;
    	NSString *path = @"/TivoMono/settings.xml";
    	NSURL *settingsURL = [NSURL fileURLWithPath:path];
    	if (!settingsURL) {
    		NSLog(@"Can't Create an URL from file %@.", path);
    		return;
    	}
    	settingsXML = [[NSXMLDocument alloc] initWithContentsOfURL:settingsURL];
    I get an error in console:
     
  4. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #4
    missing a part:

     
  5. thread starter macrumors member

    Joined:
    May 2, 2002
    Location:
    Iowa
    #5
    thanks for the tip unfortunately it's not quite clear to me what I've got to do. This might take too much hand holding for you to really help me much since I know you are quite busy. :(
    I'll keep scouring google to see if I can't find more info but it seems quite sparse.
     
  6. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #6
    Try:

    Code:
    settingsXML = [[NSXMLDocument alloc] initWithContentsOfURL:settingsURL
     options:0 error:nil];
     
  7. thread starter macrumors member

    Joined:
    May 2, 2002
    Location:
    Iowa
    #7
    damn you're good! Looks like it is reading the XML correctly. I am now trying to pull out the info of the XML. I have it reading an element in the XML with the following code:
    Code:
    		NSXMLElement *Installpath;
    	NSXMLDocument *settingsXML;
    	NSString *path = @"/TivoMono/settings.xml";
    	NSURL *settingsURL = [NSURL fileURLWithPath:path];
    		if (!settingsURL) {
    		NSLog(@"Can't Create an URL from file %@.", path);
    		return;
    	}
    		settingsXML = [[NSXMLDocument alloc] initWithContentsOfURL:settingsURL
    														   options:0 error:nil];
    		NSArray *nodes = [settingsXML nodesForXPath:@"./TiVoMono/FFMpeg_Path" error:nil];
    		Installpath = [nodes objectAtIndex:0];
    		[TestText setStringValue:Installpath];
    The XML data I want returned is /TivoMono/ffmpeg
    The TestText Output is: <FFMpeg_Path>/TivoMono/ffmpeg</FFMpeg_Path>
    Any quick way to get the format looking the way I need it to?
     
  8. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #8
    Don't know if this is of any help but you can also use the Core Foundation stuff for handling XML. The difference being that it is a C api which you might prefer. It's pretty easy to use once you have created a CFXMLTreeRef. For example, to create one from a string:-

    Code:
    NSData* xmlData =  [ sourceStr dataUsingEncoding: NSNonLossyASCIIStringEncoding ] ;
    CFXMLTreeRef tree = CFXMLTreeCreateFromData( kCFAllocatorDefault, (CFDataRef) xmlData, NULL, kCFXMLParserSkipWhitespace, kCFXMLNodeCurrentVersion ) ;
    
    Once you've got a CFXMLTreeRef you just use C function calls to walk the XML tree and extract the data you want.

    b e n
     
  9. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #9
    The CFXML functions are not good though. They don't automatically handle entities and other annoying things. If you are targeting 10.4+, then use NSXML.
     
  10. Guest

    caveman_uk

    Joined:
    Feb 17, 2003
    Location:
    Hitchin, Herts, UK
    #10
    It took me ages to figure out how to get pretty XML output. The trick is
    Code:
    NSString* xmlOutput=[xmlDoc XMLStringWithOptions:NSXMLNodePrettyPrint];
    
    where xmlDoc is an NSXMLDocument

    EDIT: Nevermind....I just answered the wrong question.

    EDIT2: You need to look at the NSXMLNode's objectValue to get what you want out of each node in your array
     
  11. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #11
    Installpath is not an NSString. So you need to use:
    Code:
    [TestText setStringValue:[Installpath stringValue]];
    To extract the NSString value from the XML element.
     
  12. thread starter macrumors member

    Joined:
    May 2, 2002
    Location:
    Iowa
    #12
    cool. that all works :)

    I've been trying to do some if statements but I am unable to get the casting right. I am trying to do something like the following:
    Code:
    if (valueFromXML == 128) {
    //DoSomething
    NSBeep();
    }
    
    I've tried a few combinations of ' and " and @ and looking online on how to cast this pointer into an int so this if statement will work to no avail.

    I am so going to be owing someone some beer here by the time I learn Cocoa well.
     
  13. thread starter macrumors member

    Joined:
    May 2, 2002
    Location:
    Iowa
    #13
    Still trying to get this working...
    I would think this would work but it does not.
    Code:
    		NSArray *audioCodecNodes = [settingsXML nodesForXPath:@"./TiVoMono/FFMpeg_AudioCodec" error:nil];
    		[audioCodecText setStringValue:[[audioCodecNodes objectAtIndex:0] stringValue]];
    		if ([(NSString *)audioCodecText isEqualToString:@"mp2"]==YES){
    			NSBeep();
    		}
    the audioCodecText box in the UI shows mp2 in it which it is reading from the XML.
     
  14. Guest

    caveman_uk

    Joined:
    Feb 17, 2003
    Location:
    Hitchin, Herts, UK
    #14
    [objectName intValue]
     

Share This Page