Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

A@ron

macrumors member
Original poster
May 2, 2002
54
0
Iowa
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!
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
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.
 

A@ron

macrumors member
Original poster
May 2, 2002
54
0
Iowa
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:
2007-02-20 22:47:30.055 System Preferences[2093] *** -[NSXMLDocument initWithContentsOfURL:]: selector not recognized [self = 0x3be9e0]
2007-02-20 22:47:30.055 System Preferences[2093] *** NSRunLoop ignoring exception '*** -[NSXMLDocument initWithContentsOfURL:]: selector not recognized [self = 0x3be9e0]' that raised during posting of delayed perform with target 352e60 and selector 'setCurrentPreference:'
 

A@ron

macrumors member
Original poster
May 2, 2002
54
0
Iowa
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.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Try:

Code:
settingsXML = [[NSXMLDocument alloc] initWithContentsOfURL:settingsURL
 options:0 error:nil];
 

A@ron

macrumors member
Original poster
May 2, 2002
54
0
Iowa
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?
 

lazydog

macrumors 6502a
Sep 3, 2005
709
6
Cramlington, UK
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
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
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.
 

caveman_uk

Guest
Feb 17, 2003
2,390
1
Hitchin, Herts, UK
The TestText Output is: <FFMpeg_Path>/TivoMono/ffmpeg</FFMpeg_Path>
Any quick way to get the format looking the way I need it to?
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
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
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?

Installpath is not an NSString. So you need to use:
Code:
[TestText setStringValue:[Installpath stringValue]];
To extract the NSString value from the XML element.
 

A@ron

macrumors member
Original poster
May 2, 2002
54
0
Iowa
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.
 

A@ron

macrumors member
Original poster
May 2, 2002
54
0
Iowa
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.
 

caveman_uk

Guest
Feb 17, 2003
2,390
1
Hitchin, Herts, UK
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.
[objectName intValue]
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.