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

3

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

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脚本:

<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>

=============================================================================== 结果 - 客户端名称:clientD(作为nodindex =“3”)

谢谢

3个回答

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 只能是文件、文件夹、行或字符串。

经过长时间的痛苦和点赞后,发现上述解决方案无法与nAnt .85及更高版本一起使用。在.85 RC中,递归功能被删除,并且从未恢复。请参见http://sourceforge.net/p/nant/bugs/275/。 - user1821052

1
<xmlpeek>任务据我所知并不支持返回多个结果。根据其官方描述:

如果XPath表达式指定了多个节点,则会使用节点索引来确定返回哪个节点的文本。

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

0

@sirdank的答案最优雅,但不适用于nAnt .85及更高版本。鉴于此,这里提供了一种简单的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。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接