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 into 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 = null) === Here is typical use of namespace map (taken from my real script): <xmlpeek file="${prjconfig}" xpath="x:Project/x:ExeName" property="newexe" failonerror="true" failonnonode="false" > <namespaces> <namespace prefix="x" uri="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="1.0" encoding="utf-8"?> <Project xmlns="http://www.gordic.cz/shared/project-config/v_1.0.0.0"> <Name>foo</Name> <Description>foobar</Description> <ExeName>footest</ExeName> </Project> === 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: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On > Behalf Of John Ludlow > Sent: Tuesday, January 24, 2006 7:19 PM > To: nant-developers@lists.sourceforge.net; > nantcontrib-developer@lists.sourceforge.net > 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 [EMAIL PROTECTED]). 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 > ======= > > 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 > ========= > 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: > ======== > - 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: > ============= > - 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="bob" age="44"> > <children> > <child name="tom" age="3"/> > <child name="dick" age="1"/> > <child name="harry" age=".5"/> > </children> > </data> > <data name="bill" age="15"> > </data> > <data name="ted" age="372"> > <children> > <child name="sarah" age="4"/> > </children> > </data> > <data name="fred" age="23"> > <children> > <child name="phil" age="5"/> > </children> > </data> > </root> > > ...and you have the following in your build script: > > <xml-foreach file="test.xml" xpath="/root/data" index="i"> > <xmlpropertybinding> > <get xpath="@name" property="name"/> > <get xpath="@age" property="age"/> > <get xpath="children/child/@name " property="child"/> > </xmlpropertybinding> > <do> > <echo message="#${i} ${name} is ${age} years old"/> > <xml-foreach file="test.xml" > xpath="/root/data[${i}]/children/child"> > <xmlpropertybinding> > <get xpath="@name" property="childname"/> > <get xpath="@age" property="age"/> > </xmlpropertybinding> > <do> > <echo message="${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 > ======= > 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="${file}" xpath="/" create="true"> > <data> > <![CDATA[ > <root> > <person name="mary" age="43"> > <child name="penelope" age="12"/> > </person> > </root> > ]]> > </data> > </xmlpoke2> > > You can embed properties within the CDATA element as well, so > you can do this: > > <property name="penelopysage" value="12"/> > > <xmlpoke2 file="${file}" xpath="/" create="true"> > <data> > <![CDATA[ > <root> > <person name="mary" age="43"> > <child name="penelope" age="${penelopysage}"/> > </person> > </root> > ]]> > </data> > </xmlpoke2> > or this: > <xmlpoke2 file="${file}" xpath="/root" create="true"> > <data> > <![CDATA[ > ${xml::get-xml(file, '/root')} > <person name="mary" age="43"> > <child name="penelope" age="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=k&kid3432&bid#0486&dat1642 > _______________________________________________ > nant-developers mailing list > nant-developers@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/nant-developers > ------------------------------------------------------- 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=lnk&kid3432&bid#0486&dat1642 _______________________________________________ nant-developers mailing list nant-developers@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nant-developers