【问题标题】:How to Get Two Separate Siblings with XPath如何使用 XPath 获得两个独立的兄弟姐妹
【发布时间】:2019-03-21 19:10:55
【问题描述】:

我正在尝试调用 Jenkins XML API 以从其 REST 端点检索特定的信息集(... 表示内容中存在类似的同级元素,但为简洁起见将其排除在外):

<workflowRun _class="org.jenkinsci.plugins.workflow.job.WorkflowRun">
   <action _class="hudson.model.CauseAction">
      <cause _class="hudson.triggers.TimerTrigger$TimerTriggerCause">
         <shortDescription>Started by timer</shortDescription>
      </cause>
   </action>
   <action _class="hudson.model.ParametersAction">
      <parameter _class="hudson.model.StringParameterValue">
         <name>projectName</name>
         <value>My-Proj</value>
      </parameter>
      <parameter _class="hudson.model.StringParameterValue">
         <name>NodeParam</name>
         <value>UY-DO1</value>
      </parameter>
      ...
   </action>
   <action/>
   <action/>
   <action/>
   <action/>
   <action _class="org.jenkinsci.plugins.workflow.cps.EnvActionImpl"/>
   <action/>
   <action _class="hudson.tasks.junit.TestResultAction">
      <failCount>21</failCount>
      <skipCount>6</skipCount>
      <totalCount>223</totalCount>
      <urlName>myReport</urlName>
   </action>
   <action/>
   <action/>
   <action/>
   <action _class="org.jenkinsci.plugins.workflow.job.views.FlowGraphAction"/>
   <action/>
   <action/>
   <building>false</building>
   ...
   <result>FAILURE</result>
   <timestamp>1553145960340</timestamp>
   ...
</workflowRun>

我只对获取以下信息感兴趣:

   <action _class="hudson.tasks.junit.TestResultAction">
      <failCount>21</failCount>
      <skipCount>6</skipCount>
      <totalCount>223</totalCount>
      <urlName>myReport</urlName>
   </action>       
   <timestamp>1553145960340</timestamp>

但是,我找不到一次性获取所有这些数据的 XPath 命令。我可以运行两个单独的调用来检索所需的信息,但这需要两个单独的服务器行程。我想知道是否有一个 XPath 命令可以用来一次性检索目标 &lt;action&gt;&lt;timestamp&gt;

https://jenkins_host/job/MyApp/job/Some_Jenkins_Job/lastCompletedBuild/api/xml?xpath=/workflowRun/action[@_class='hudson.tasks.junit.TestResultAction']

这得到了我们:

   <action _class="hudson.tasks.junit.TestResultAction">
      <failCount>21</failCount>
      <skipCount>6</skipCount>
      <totalCount>223</totalCount>
      <urlName>myReport</urlName>
   </action>  

和时间戳分开(注意从xpath切换到tree):

https://jenkins_host/job/MyApp/job/Some_Jenkins_Job/lastCompletedBuild/api/xml?tree=timestamp

结果为:

<workflowRun _class="org.jenkinsci.plugins.workflow.job.WorkflowRun">
   <timestamp>1553145960340</timestamp>
</workflowRun>

我尝试使用treexpath 的组合,但出现错误:

https://jenkins_host/job/MyApp/job/Some_Jenkins_Job/lastCompletedBuild/api/xml?tree=timestamp&xpath=/workflowRun/action[@_class='hudson.tasks.junit.TestResultAction']

似乎它们不能混淆。我什至尝试使用它无济于事:

xml?xpath=/workflowRun/action[@_class='hudson.tasks.junit.TestResultAction']&/workflowRun/timestamp

xml?xpath=/workflowRun/action[@_class='hudson.tasks.junit.TestResultAction']&xpath=/workflowRun/timestamp

知道如何使用单个 XPath 获取两组数据吗?

【问题讨论】:

    标签: json xml jenkins xpath


    【解决方案1】:

    下一个是完全有效的 XPath 1.0 表达式,但我不知道您的 REST 端点是否可以解析它...

    /workflowRun
       /action[@_class='hudson.tasks.junit.TestResultAction']
    |/workflowRun
       /action[@_class='hudson.tasks.junit.TestResultAction']
          /following-sibling::timestamp[1]
    

    或者没有联合(强制使用Kaysian方法):

    /workflowRun
       /*[self::action/@_class='hudson.tasks.junit.TestResultAction' or
          self::timestamp[
             count(.|../action[@_class='hudson.tasks.junit.TestResultAction']/following-sibling::timestamp[1]) 
             = count(../action[@_class='hudson.tasks.junit.TestResultAction']/following-sibling::timestamp[1])
         ]]
    

    两者的关键是选择引用元素(action)然后跟随兄弟timestamp而不仅仅是每个timestamp

    【讨论】:

    • 谢谢。我不得不稍微更新你的答案才能让它发挥作用,但解决方案的核心几乎可以解决这个问题。
    【解决方案2】:

    作为一种选择,通过以下运算符之一联合分组表达​​式:|or。选择以下解决方案之一:

    1. |-运营商:

    (//action[@_class='hudson.tasks.junit.TestResultAction']/descendant-or-self::*)|//timestamp

    1. or-运营商:

      //*[self::action[@_class='hudson.tasks.junit.TestResultAction'] or self::timestamp]/descendant-or-self::*

    【讨论】:

    • 请注意//action[@_class='hudson.tasks.junit.TestResultAction']/descendant-or-self::*//action[@_class='hudson.tasks.junit.TestResultAction']//* 相同。虽然不知道从哪里来。不是来自问题。
    • 不,表达式action//*不是返回一个自身节点,但是作者想得到这个action-node
    • 你是对的。您将失去self 斧头。但是为什么你选择action和后代并不清楚问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 2020-08-15
    • 2021-01-10
    • 1970-01-01
    相关资源
    最近更新 更多