如何使用xmlpeek在Nant中获取多个xml节点?

时间:2013-06-27 08:17:42

标签: .net nant

我希望得到“name”之后的所有节点值。但似乎Nant xmlpeek只能从xml获得一个节点。有没有其他方法可以在“名称”之后获取所有节点的名称?

xml文件:

<?xml version="1.0" encoding="utf-8" ?>
<QAEnvironment xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <user>
                <name value="clientA" />
        <name value="clientB" />
        <name value="clientC" />
        <name value="clientD" />
    </user>
</QAEnvironment>

=============================================== ===============================

nant script:

<xmlpeek
    file="A.xml"
    xpath="/x:QAEnvironment/x:user/x:name/@value"
    property="clientName"
    nodeindex="3">
     <namespaces>
        <namespace prefix="x" uri="http://schemas.microsoft.com/developer/msbuild/2003" />
    </namespaces> 
    <echo message="clientName: ${clientName}" />
</xmlpeek>

=============================================== ================================ 结果 - clientName:clientD(作为nodindex =“3”)

由于

3 个答案:

答案 0 :(得分:1)

据我所知,<xmlpeek>任务并非旨在返回多个结果。根据其官方说明:

  

如果XPath表达式指定节点索引为多个节点   用于确定返回哪些节点的文本。

如果您有可靠的方法来确定同名节点的数量,您可以尝试在这些节点上运行<foreach>循环。否则,我认为你唯一的选择就是为此创建一个自定义的NAnt任务。就我所见,nant.contrib项目没有任何用于此目的的东西。

答案 1 :(得分:1)

我唯一的建议是递归“循环”:

<target name="get.xml.nodes">
    <property name="counter" value="1" if="${not property::exists(counter)}" />
    <property name="counter" value="${counter + 1}" if="${property::exists(counter)}" />

    <property name="temp" value="${node}" if="${property::exists(node)}"/>

    <xmlpeek file="file.xml" nodeindex="${counter}" xpath="/node" property="node" failonerror="false" />

    <call target="get.xml.nodes" unless="${node == temp}" />
<target>

像Yan说的那样,我认为你不能在技术上这样做,<foreach>实际上并不支持这一点。 LoopItems只能是文件,文件夹,行或字符串。

答案 2 :(得分:0)

@sirdank的答案是最优雅的,但对于.85及更高版本的nAnt版本不起作用。鉴于此,Nant和嵌入式VB.net的简单组合将实现相同的目标:

<target name="parseNodes">


   <script language="VB">
     <references> 
<include name="System.dll" /> 
<include name="System.Xml.dll" /> 
     </references> 
     <imports> 
       <import namespace="System.Text.RegularExpressions" /> 
       <import namespace="System.Xml" /> 
       <import namespace="System.Xml.XPath" /> 
     </imports> 
     <code><![CDATA[

public shared sub ScriptMain(thisProject as Project)
    Dim xmlDoc as new XmlDocument()
    Dim nodes as XmlNodeList
    Dim packageString as string

    xmlDoc.Load(thisProject.properties("path"))

    nodes = xmlDoc.GetElementsByTagName("myNode")

    for each node as XmlNode in nodes
        nodeString += package.Attributes.itemOf("someAttribute").value & ","    
    next

    thisProject.properties("nodes") = nodeString

 end sub

     ]]>
     </code>
   </script>


   <echo message="Nodes: ${nodes}" />       

<foreach item="String" in="${nodes}" delim="," property="node">
        <echo message="${node}" />
</foreach>


 </target>

请注意,如果你有一个大文件,你应该在VB代码中使用XPath。