Mike,

Thanks so much for your feedback.  I used your suggestion with a little
wrinkle.  Instead of creating unique names for each node in the Xml
file, I gave each node an attribute with a unique ID.  That way, the
file can still be parsed by other Xml parsers without confusion.  This
is what I came up with:

Sample XML file:

<?xml version="1.0"?>
<DirDiff>
  <FileDirItems>
    <FileDirItem Id="1" Type="File" Status="Modified"
Path="DNSLookup.asp" />
    <FileDirItem Id="2" Type="File" Status="Modified"
Path="encryption.asp" />
    <FileDirItem Id="3" Type="File" Status="Modified" Path="err404.asp"
/>
    <FileDirItem Id="4" Type="File" Status="Modified" Path="error.asp"
/>
    <FileDirItem Id="5" Type="File" Status="Modified" Path="error.aspx"
/>
    <FileDirItem Id="6" Type="File" Status="Modified"
Path="errorauth.aspx" />
    <FileDirItem Id="7" Type="File" Status="Added" Path="genericPub.asp"
/>
    <FileDirItem Id="8" Type="File" Status="Added"
Path="getchart_id.asp" />
    <FileDirItem Id="9" Type="File" Status="Added"
Path="glossary_windoid.asp" />
  </FileDirItems>
</DirDiff>

Nant task code:

<target name="default" >
        <property name="fileName" value="ChangeList.xml" />
        <xmllist file="${fileName}"
xpath="/DirDiff/FileDirItems/FileDirItem/@Id" property="idList" />

        <foreach item="String" delim="," in="${idList}"
property="itemId" >

                <xmllist file="${fileName}"
xpath="/DirDiff/FileDirItems/FileDirItem [...@id='${itemId}']/@Path"
property="filePath" />
                <xmllist file="${fileName}"
xpath="/DirDiff/FileDirItems/FileDirItem [...@id='${itemId}']/@Status"
property="fileStatus" />

                <echo message="itemId = ${itemId}, filePath =
${filePath}, fileStatus = ${fileStatus}" />

                <!-- Now, do the work  -->
        </foreach>
</target>


Much appreciated.

Ken Parrish
Gomez, Inc.

________________________________________________________________________
_____________________


-----Original Message-----
From: Mike Frederick [mailto:mikeyf...@att.net] 
Sent: Thursday, January 29, 2009 12:33 PM
To: nant-users@lists.sourceforge.net
Subject: [NAnt-users] Navigating XML documents ...

It is a little painful, but it is possible.  The idea is to be able to 
address each FileItem node individually.  If each Path property is 
unique across all of the FileItem nodes, then you can use that property 
to "pick-out" each FileItem node:

<project name="Ken" default="go">
    <property name="XMLFile" value="Ken.xml"/>
    <property name="xpath" value="/MyFileList/FileItems/FileItem"/>
    <target name="go">
        <xmllist file="${XMLFile}" xpath="${xpath}/@Path" 
property="pathlist"/>
        <foreach item="String" delim="," in="${pathlist}"
property="path">
            <echo>File: ${path}</echo>
            <xmllist file="${XMLFile}" xpath="${xpath} 
[...@path='${path}']/@Status" property="status"/>
            <xmllist file="${XMLFile}" xpath="${xpath} 
[...@path='${path}']/@Mode" property="mode"/>
            <echo>  status: ${status}, mode: ${mode}</echo>
            <echo />
        </foreach>
    </target>
</project>

Since you have gotten this far, I will mention that I tend to address 
this situation by creating nodename that are unique, such as:

<?xml version="1.0"?>
<MyFileList>
    <summary>
    </summary>
    <FileItems>
        <File01 Path="file01.txt" Status="good" Mode="ok" />
        <File02 Path="file02.txt" Status="bad" Mode=" ok" />
        <File03 Path="file03.txt" Status="good" Mode="notok"/>
        <File04 Path="file04.txt" Status="ignore" Mode="ok" />
        <File05 Path="file05.txt" Status="bad" Mode="ok" />
    </FileItems>
</MyFileList>

which is ugly from a schema perspective, but I have a mod to <xmllist> 
that allows me to do:

<project name="Ken" default="go">
    <property name="XMLFile" value="Ken.xml"/>
    <property name="xpath" value="/MyFileList/FileItems"/>
    <target name="go">
        <xmllist file="${XMLFile}" xpath="${xpath}/*"
property="filelist"/>
        <foreach item="String" delim="," in="${filelist}" 
property="fileitem">
            <xmllist file="${XMLFile}" 
xpath="${xpath}/${fileitem}/@Path" property="path"/>
            <xmllist file="${XMLFile}" 
xpath="${xpath}/${fileitem}/@Status" property="status"/>
            <xmllist file="${XMLFile}" 
xpath="${xpath}/${fileitem}/@Mode" property="mode"/>
            <echo>File: ${path}</echo>
            <echo>  status: ${status}, mode: ${mode}</echo>
            <echo />
        </foreach>
    </target>
</project>

which I like a lot better from a programming perspective.  The mod I 
made was to allow a file nodename to be a "*", which is interpreted as 
"return a list of all child nodenames".

The idea is to
> Thanks for the reference to <xmllist>.  I have built this code into my
> standard extension DLL and it seems to be working as advertised.
>
> However, there is a part of the problem that I have yet to find a good
> solution.  In the example below, I can generate a list of all the
'Path'
> attributes, or all the 'Status' attributes.  However, there is no
> practical way (that I can think of) to iterate over these two lists
> simultaneously.  
>
> What I really need is to 'fetch' each <FileItem> node, one at a time,
> then gather the various attributes set for that node.  Then, iterate
to
> the next <FileItem> node in the file.
>
> Is there any way to do this via <xmllist> or with some combination of
> other Nant tasks?
>
> <?xml version="1.0"?>
> <MyFileList>
>       <summary>
>       </summary>
>       <FileItems>
>               <FileItem Path="file01.txt" Status="good" Mode="ok" />
>               <FileItem Path="file02.txt" Status="bad" Mode=" ok" />
>               <FileItem Path="file03.txt" Status="good" Mode="notok"
> />
>               <FileItem Path="file04.txt" Status="ignore" Mode="ok" />
>               <FileItem Path="file05.txt" Status="bad" Mode="ok" />
>       </FileItems>
> </MyFileList>
>
> The only other solution I can find is to execute three  <xmllist>
tasks
> and fetch the 'Path' , 'Status' and 'Mode' attributes into separate
> comma separated strings.  Then, perform string manipulations in such a
> way as to fetch the 'Path' , 'Status' and 'Mode' attributes in
> parallels.
>
> It seems like there must be a more straightforward and direct
solutions
> to this?  Has anyone attempted to modify the <xmllist> task to fetch
and
> xml element, then it's subsequent attributes?
>
> Thanks,
>
> Ken Parrish
> Gomez, Inc.
>
>   


------------------------------------------------------------------------
------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
NAnt-users mailing list
NAnt-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nant-users

------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
NAnt-users mailing list
NAnt-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nant-users

Reply via email to