From: John L. <joh...@gm...> - 2006-01-30 17:25:49
|
Actually, scratch that. It seems that it needs to implement IConvertible i= f it needs to pass to that function. I'll carry on looking at it, and let you know how I get on. On 30/01/06, John Ludlow <joh...@gm...> wrote: > > Hi, Martin, > > I've knocked together the following two functions. I haven't tested them > yet, but they don't exactly work ideally anyway. I want to be able to ha= ve > a params array of XmlNamespace[] as the last parameter, but it won't let = me > do that because, apparently, XmlNamespace needs to implement IConvertible= . > I've taken a quick gander at this and it looks like implementing this mig= ht > be a big job. > > If I can get that working, the syntax would be something like > > ${xml::get-value-using-ns('test.xml', '/data/something', > xml::get-ns('x', 'http://x-uri' <http://x-uri%27>), xml::get-ns('y', 'htt= p://y-uri'))<http://y-uri%27%29%29> > } > > OTOH, there might be a good reason that XmlNamespace doesn't support this > interface. > > What do you think? > > [Function("get-value-using-ns")] > public static string GetXmlValue(string xmlFile, string xPath, > XmlNamespace xmlNamespace) > { > XmlDocument xd =3D new XmlDocument(); > xd.Load(xmlFile); > > XmlNamespaceManager nsMgr =3D new XmlNamespaceManager( > xd.NameTable); > > XmlNamespace xns =3D new XmlNamespace(); > if (xmlNamespace.IfDefined && !xmlNamespace.UnlessDefined) > { > nsMgr.AddNamespace(xmlNamespace.Prefix, xmlNamespace.Uri)= ; > } > > string s =3D xd.SelectSingleNode(xPath, nsMgr).Value; > > return s; > } > > [Function("get-ns")] > public static XmlNamespace GetNamespace(string prefix, string uri= ) > { > XmlNamespace xn =3D new XmlNamespace(); > xn.Prefix =3D prefix; > xn.Uri =3D uri; > > return xn; > } > > BTW, I couldn't get your example of a namespace working. It kept > complaining about the version number in the preprocessor. I copied the o= ne > from the NAnt help which worked ok. > > On 30/01/06, Martin Aliger <mar...@go...> wrote: > > > > Hello, > > > > I like it very much. Expecially functions. Bad luck I personally need > > namespace support, since mine xmls have some namespace in it. And even > > default namespace needs specification in xpaths :-( > > > > Maybe there could be some elegant way how to pass namespace mapping int= o > > > > functions. New type come to my mind. It could be elegant perhaps. > > > > btw: does nant functions support overloading and/or default parameter > > value? > > bool xml::value-exists (string xmlFile, string xPath, > > NamespaceMap nsMap =3D null) > > > > > > =3D=3D=3D > > > > Here is typical use of namespace map (taken from my real script): > > > > <xmlpeek > > file=3D"${prjconfig}" > > xpath=3D"x:Project/x:ExeName" > > property=3D"newexe" > > failonerror=3D"true" > > failonnonode=3D"false" > > > > > <namespaces> > > > > <namespace > > prefix=3D"x" uri=3D"http://www.gordic.cz/shared/project-config/v_1.0.0.= 0"/> > > </namespaces> > > > > </xmlpeek> > > > > > > And sample xml file is here (changed to protect innocent): > > > > <?xml version=3D"1.0" encoding=3D"utf-8"?> > > <Project xmlns=3D" http://www.gordic.cz/shared/project-config/v_1.0.0.0= "> > > <Name>foo</Name> > > <Description>foobar</Description> > > <ExeName>footest</ExeName> > > </Project> > > > > =3D=3D=3D > > > > I missed xml-foreach once too, but nowadays I do not need it. Still it > > could > > be worth addition to NAnt(Contrib) tasks! > > > > Martin Aliger > > > > > > > -----Original Message----- > > > From: nan...@li... > > > [mailto:nan...@li...] On > > > Behalf Of John Ludlow > > > Sent: Tuesday, January 24, 2006 7:19 PM > > > To: nan...@li...; > > > nan...@li... > > > Subject: [nant-dev] New XML tasks and functions > > > > > > Hi, there > > > > > > Recently I mentioned on the NAnt Dev list that I have been > > > working on XML-handling functionality. I've got further than > > > I had last time, so I thought about summarising what I've > > > done here (I'm also happy to share the code and/or binaries, > > > so if you want either of these to check it out for yourself, > > > just email me at joh...@gm...). I've put my code > > > into an assembly, tested it, and am currently contemplating > > > writing some unit tests for it. > > > Before I go through that, though, I wanted to get some > > > feedback and a better idea of what people thought of this. > > > > > > This is what I have so far: > > > > > > Functions > > > =3D=3D=3D=3D=3D=3D=3D > > > > > > bool xml::value-exists (string xmlFile, string xPath) > > > -------------------------------------------------------------- > > > ----------- > > > Tests whether a specified xpath query returns a value. If > > > this gets a NullReferenceException (usually means an XML > > > value doesn't exist). > > > > > > string xml::get-value (string xmlFile, string xPath) > > > -------------------------------------------------------------- > > > --------- > > > Gets a value returned by an XPath query. Throws an error if > > > the node specified in the xpath is not found. Duplicates > > > some of <xmlpeek>'s functionality, but enables you to use > > > ${x} syntax to get an xml value. > > > This fits in with the idea that being able to use this > > > functionality is nicer if all you want is information. > > > However, it does not support namespaces like xmlpeek does. > > > > > > string xml::get-value-without-failing (string xmlFile, string xPath) > > > -------------------------------------------------------------- > > > ----------------------------- > > > Gets a value returned by an XPath query. As above, but does > > > not an error if the node specified in the XPath is not found, > > > instead returning a blank string. > > > > > > string xml::get-xml (string xmlFile, string xPath) Gets the > > > InnerXml property of an XML node returned by an XPath query. > > > > > > int xml::count (string xmlFile, string xPath) Gets the number > > > of nodes in a document that match the specified XPath query. > > > > > > Tasks > > > > > > xml-foreach > > > =3D=3D=3D=3D=3D=3D=3D=3D=3D > > > Iterates through an XML document. I thought about making > > > this part of the ForEach task, but there seemed to be a > > > significant difference in functionality, especially > > > concerning getting the details of each item in the > > > iteration. For this reason, I decided to make a separate task. > > > The syntax is explained below: > > > > > > Attributes: > > > =3D=3D=3D=3D=3D=3D=3D=3D > > > - file: string. XML file to iterate > > > - xpath: string. XPath. The task will essentially iterate > > > through the list of nodes that match this query. > > > - index: string. Optional. A property that can contain > > > the index of a returned result in the node list. You can use > > > this to find this node in the doument again, especially > > > useful for nested loops. By default doesn't set any property. > > > > > > Nested elements: > > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > > - do: The tasks to run on each iteration > > > > > > - xmlpropertybinding: Runs XPath queries on the result, > > > putting the returned value in a property. > > > > > > - xmlpropertybinding/get > > > > > > Attributes > > > ----------------------------------------------- > > > - xpath: string. The XPath query to run > > > - property: string. The property to populate with the value > > > returned by the XPath query. > > > - failonempty: bool. Optional. Specifies whether or not > > > the script should fail if the node specified in the XPath > > > cannot be found. > > > Default is false. > > > > > > Example: > > > > > > Assuming you have the following in a file called test.xml > > > > > > <root> > > > <data name=3D"bob" age=3D"44"> > > > <children> > > > <child name=3D"tom" age=3D"3"/> > > > <child name=3D"dick" age=3D"1"/> > > > <child name=3D"harry" age=3D".5"/> > > > </children> > > > </data> > > > <data name=3D"bill" age=3D"15"> > > > </data> > > > <data name=3D"ted" age=3D"372"> > > > <children> > > > <child name=3D"sarah" age=3D"4"/> > > > </children> > > > </data> > > > <data name=3D"fred" age=3D"23"> > > > <children> > > > <child name=3D"phil" age=3D"5"/> > > > </children> > > > </data> > > > </root> > > > > > > ...and you have the following in your build script: > > > > > > <xml-foreach file=3D"test.xml" xpath=3D"/root/data" index=3D"i"> > > > <xmlpropertybinding> > > > <get xpath=3D"@name" property=3D"name"/> > > > <get xpath=3D"@age" property=3D"age"/> > > > <get xpath=3D" children/child/@name " property=3D"child"/> > > > </xmlpropertybinding> > > > <do> > > > <echo message=3D"#${i} ${name} is ${age} years old"/> > > > <xml-foreach file=3D" test.xml" > > > xpath=3D"/root/data[${i}]/children/child"> > > > <xmlpropertybinding> > > > <get xpath=3D"@name" property=3D"childname"/> > > > <get xpath=3D"@age" property=3D"age"/> > > > </xmlpropertybinding> > > > <do> > > > <echo message=3D"${name}::${childname} is ${age} years old"= /> > > > </do> > > > </xml-foreach> > > > </do> > > > </xml-foreach> > > > > > > ...you'll get this returned: > > > > > > [echo] #1 bob is 44 years old > > > [echo] bob::tom is 3 years old > > > [echo] bob::dick is 1 years old > > > [echo] bob::harry is .5 years old > > > [echo] #2 bill is 15 years old > > > [echo] #3 ted is 372 years old > > > [echo] ted::sarah is 4 years old > > > [echo] #4 fred is 23 years old > > > [echo] fred::phil is 5 years old > > > > > > xmlpoke2 > > > =3D=3D=3D=3D=3D=3D=3D > > > Like <xmlpoke>, but writes a whole structure, rather than a > > > single value. Especially useful if you want to dynamically > > > create an XML file in your script. While this is currently > > > possible in NAnt using a combination of <echo> (or <copy> if > > > you have a template copy of the > > > file) and <xmlpoke>, it involves a lot of escape characters. > > > This new task allows you to dynamically create your xml > > > structure in your build script and write it all in one go. > > > > > > Attributes > > > -------------- > > > - file: string. The xml file to write to. > > > - xpath: string. Where to write to in the document. To > > > write at the root, use "/" > > > - create: bool. Optional. Specifies whether the task > > > should create the file if it can't find it. Defaults to true. > > > > > > Nested Elements > > > > > > - data: the XML data to write. You should put this into a CDATA > > > element.Example: > > > > > > <xmlpoke2 file=3D"${file}" xpath=3D"/" create=3D"true"> > > > <data> > > > <![CDATA[ > > > <root> > > > <person name=3D"mary" age=3D"43"> > > > <child name=3D"penelope" age=3D"12"/> > > > </person> > > > </root> > > > ]]> > > > </data> > > > </xmlpoke2> > > > > > > You can embed properties within the CDATA element as well, so > > > you can do this: > > > > > > <property name=3D"penelopysage" value=3D"12"/> > > > > > > <xmlpoke2 file=3D"${file}" xpath=3D"/" create=3D"true"> > > > <data> > > > <![CDATA[ > > > <root> > > > <person name=3D"mary" age=3D"43"> > > > <child name=3D"penelope" age=3D"${penelopysage}"/> > > > </person> > > > </root> > > > ]]> > > > </data> > > > </xmlpoke2> > > > or this: > > > <xmlpoke2 file=3D"${file}" xpath=3D"/root" create=3D"true"> > > > <data> > > > <![CDATA[ > > > ${xml::get-xml(file, '/root')} > > > <person name=3D"mary" age=3D"43"> > > > <child name=3D"penelope" age=3D"12"/> > > > </person> > > > ]]> > > > </data> > > > </xmlpoke2> > > > > > > ...which would append data to the end of your document. > > > > > > Neither of these is perfect at the moment, but I wanted to > > > see if anyone thought they'd be useful. The <xmlpoke2> task > > > could maybe do with namespace support (don't know much about > > > that) and I reckon it's just begging to be merged into the > > > main <xmlpoke> task. If people think they could be useful, > > > then I might do some more work on them, or if you want to > > > look at the source or try them out yourself just email me. > > > > > > Cheers > > > > > > John > > > > > > > > > ------------------------------------------------------- > > > This SF.net email is sponsored by: Splunk Inc. Do you grep > > > through log files for problems? Stop! Download the new AJAX > > > search engine that makes searching your log files as easy as > > > surfing the web. DOWNLOAD SPLUNK! > > > http://sel.as-us.falkag.net/sel?cmd=3Dk&kid=103432&bid#0486&dat=12164= 2<http://sel.as-us.falkag.net/sel?cmd=3Dk&kid%103432&bid#0486&dat%121642> > > > _______________________________________________ > > > nant-developers mailing list > > > nan...@li... > > > https://lists.sourceforge.net/lists/listinfo/nant-developers > > > > > > > > |