Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml XSLT:按值分组_Xml_Xslt - Fatal编程技术网

Xml XSLT:按值分组

Xml XSLT:按值分组,xml,xslt,Xml,Xslt,当integer=4时,我想使用xslt对下面的xml进行分组,然后循环遍历每个dict,检查每个元素是否有integer=5,然后将变量设置为pass only,以及是否有任何整数值为7且状态为fail 有什么建议吗 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList

当integer=4时,我想使用xslt对下面的xml进行分组,然后循环遍历每个dict,检查每个元素是否有integer=5,然后将变量设置为pass only,以及是否有任何整数值为7且状态为fail

有什么建议吗

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList1.0.dtd">
<plist version="1.0">
<dict>
<key>All Samples</key>
<array>
<dict>
<key>LogType</key>
<string>Start</string>
<key>Message</key>
<string>START:Certificate and Genre filter tests</string>
<key>Timestamp</key>
<date>2012-06-25T10:49:02Z</date>
<key>Type</key>
<integer>4</integer>
</dict>
<dict>
<key>LogType</key>
<string>Pass</string>
<key>Message</key>
<string>Navigation title bar should contain genre in card view : ACTION &amp; ADVENTURE</string>
<key>Timestamp</key>
<date>2012-06-25T10:49:13Z</date>
<key>Type</key>
<integer>5</integer>
</dict>
<dict>
<key>LogType</key>
<string>Pass</string>
<key>Message</key>
<string>START: certificate tests filter tests</string>
<key>Timestamp</key>
<date>2012-06-25T10:49:02Z</date>
<key>Type</key>
<integer>4</integer>
</dict>
<dict>
<key>LogType</key>
<string>Pass</string>
<key>Message</key>
<string>Navigation title bar should contain genre in card view : ACTION &amp; ADVENTURE</string>
<key>Timestamp</key>
<date>2012-06-25T10:49:13Z</date>
<key>Type</key>
<integer>5</integer>
</dict>
<dict>
<key>LogType</key>
<string>Fail</string>
<key>Message</key>
<string>Navigation title bar should contain genre in card view : ACTION &amp; ADVENTURE</string>
<key>Timestamp</key>
<date>2012-06-25T10:49:13Z</date>
<key>Type</key>
<integer>7</integer>
</dict>
</array>
</dict>
</plist>

expected result  in table view with format


| Test Name | test steps |   Test result|
START : GENRE FILTER TEST |    | FAIL ( background color to red)
test step1 | Navigation title bar should contain genre in card view | PASS
test step2 | Navigation title bar should contain genre in card view | FAIL

|START : certificate tests filter tests |    | PASS ( background color to green)
|test step 1 | Navigation title bar should contain genre in card view | PASS

所有样品
对数型
开始
消息
开始:证书和类型筛选测试
时间戳
2012-06-25T10:49:02Z
类型
4.
对数型
通过
消息
导航标题栏应包含卡片视图中的类型:动作和;冒险
时间戳
2012-06-25T10:49:13Z
类型
5.
对数型
通过
消息
开始:证书测试筛选测试
时间戳
2012-06-25T10:49:02Z
类型
4.
对数型
通过
消息
导航标题栏应包含卡片视图中的类型:动作和;冒险
时间戳
2012-06-25T10:49:13Z
类型
5.
对数型
失败
消息
导航标题栏应包含卡片视图中的类型:动作和;冒险
时间戳
2012-06-25T10:49:13Z
类型
7.
格式为的表视图中的预期结果
|测试名称|测试步骤|测试结果|
开始:类型筛选测试| |失败(背景色变为红色)
测试步骤1 |导航标题栏应包含卡片视图中的类型|通过
测试步骤2 |导航标题栏应包含卡片视图中的类型|失败
|开始:证书测试过滤测试| |通过(背景色变为绿色)
|测试步骤1 |导航标题栏应包含卡片视图中的类型|通过
谢谢,
bob

实现这一点的一种方法是定义一个键,通过前面整数为4的第一个同级查找dict元素

<xsl:key 
   name="test" 
   match="dict[integer[preceding-sibling::key[1]='Type']!=4]" 
  use="generate-id(
       preceding-sibling::dict[integer[preceding-sibling::key[1]='Type']=4][1]
    )" />
<xsl:apply-templates 
   select="dict
     [key='All Samples']/array/dict[integer[preceding-sibling::key[1]='Type']=4]" />

然后,首先将所有dict元素与integer=4进行匹配

<xsl:key 
   name="test" 
   match="dict[integer[preceding-sibling::key[1]='Type']!=4]" 
  use="generate-id(
       preceding-sibling::dict[integer[preceding-sibling::key[1]='Type']=4][1]
    )" />
<xsl:apply-templates 
   select="dict
     [key='All Samples']/array/dict[integer[preceding-sibling::key[1]='Type']=4]" />

然后,您可以编写一个模板—存在“Fail”元素的模板,并相应地处理它们

<xsl:template 
   match="dict
     [key('test', generate-id())[string[preceding-sibling::key[1]='LogType']='Fail']]">

所有其他匹配的dict元素都将是成功元素

然后要输出每个单独测试的结果,您可以在键中查找它们

<xsl:apply-templates select="key('test', generate-id())" mode="results" />

注意,需要使用模式,因为将有多个模板匹配dict元素,因此需要区分它们

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" indent="yes"/>
   <xsl:key name="test" match="dict[integer[preceding-sibling::key[1]='Type']!=4]" use="generate-id(preceding-sibling::dict[integer[preceding-sibling::key[1]='Type']=4][1])"/>

   <xsl:template match="plist">
      <xsl:variable name="dicts" select="dict[key='All Samples']/array/dict[integer[preceding-sibling::key[1]='Type']=4]"/>       
      <table>
         <tr>
            <td>
               <xsl:text>Test Name</xsl:text>
            </td>
            <td>
               <xsl:text>Test Steps</xsl:text>
            </td>
            <td>
               <xsl:text>Test Result</xsl:text>
            </td>
         </tr>
      <xsl:apply-templates select="$dicts"/>
      </table>
      <xsl:variable name="fails" select="count($dicts[key('test', generate-id())[string[preceding-sibling::key[1]='LogType']='Fail']])" />
      <xsl:value-of select="concat('total tests passed = ', count($dicts) - $fails)" />
      <br />
      <xsl:value-of select="concat('total tests failed = ', $fails)" /> 
   </xsl:template>

   <xsl:template match="dict[key('test', generate-id())[string[preceding-sibling::key[1]='LogType']='Fail']]">
      <xsl:call-template name="dict">
         <xsl:with-param name="type" select="'Fail'"/>
         <xsl:with-param name="colour" select="'#FF0000'" />
      </xsl:call-template>
   </xsl:template>

   <xsl:template match="dict" name="dict">
      <xsl:param name="type" select="'Pass'"/>
      <xsl:param name="colour" select="'#00FF00'" />
      <tr>
         <td>
            <xsl:value-of select="string[preceding-sibling::key[1]='Message']"/>
         </td>
         <td>
         </td>
         <td style="background-color:{$colour}">
            <xsl:value-of select="$type"/>
         </td>
      </tr>
      <xsl:apply-templates select="key('test', generate-id())" mode="results" />
   </xsl:template>

   <xsl:template match="dict" mode="results">
      <tr>
         <td>
            <xsl:value-of select="concat('Test Step ', position())" />
         </td>
         <td>
            <xsl:value-of select="string[preceding-sibling::key[1]='Message']"/>
         </td>
         <td>
            <xsl:value-of select="string[preceding-sibling::key[1]='LogType']"/>
         </td>
      </tr>
   </xsl:template>
</xsl:stylesheet>

测试名称
测试步骤
测试结果

当应用于XML示例时,将输出以下内容

<table>
  <tr>
     <td>Test Name</td>
     <td>Test Steps</td>
     <td>Test Result</td>
  </tr>
  <tr>
     <td>START:Certificate and Genre filter tests</td>
     <td/>
     <td style="background-color:#00FF00">Pass</td>
  </tr>
  <tr>
     <td>Test Step 1</td>
     <td>Navigation title bar should contain genre in card view : ACTION &amp; ADVENTURE</td>
     <td>Pass</td>
  </tr>
  <tr>
     <td>START: certificate tests filter tests</td>
     <td/>
     <td style="background-color:#FF0000">Fail</td>
  </tr>
  <tr>
     <td>Test Step 1</td>
     <td>Navigation title bar should contain genre in card view : ACTION &amp; ADVENTURE</td>
     <td>Pass</td>
  </tr>
  <tr>
     <td>Test Step 2</td>
     <td>Navigation title bar should contain genre in card view : ACTION &amp; ADVENTURE</td>
     <td>Fail</td>
  </tr>
</table>
total tests passed = 1 
<br/>
total tests failed = 1 

测试名称
测试步骤
测试结果
开始:证书和类型筛选测试
通过
测试步骤1
导航标题栏应包含卡片视图中的类型:动作和;冒险
通过
开始:证书测试筛选测试
失败
测试步骤1
导航标题栏应包含卡片视图中的类型:动作和;冒险
通过
测试步骤2
导航标题栏应包含卡片视图中的类型:动作和;冒险
失败
通过的测试总数=1

失败的测试总数=1

请注意使用命名模板来使用“成功”和“失败”行的共享代码。

我没有看到您说您尝试过的“下面的代码”-它在哪里?另外,您能提供一个输出应该是什么样子的Xml示例吗?完全不清楚。“拆分xml”到底是什么意思?请在通过和失败的情况下显示您的预期输出。请说明您是否能够使用XSLT 2.0。使用2.0比1.0更容易解决分组问题。我只想使用xslt 1.0版,因为Xcode UI Automation instrument有限公司我已更正了XML示例,因为它的格式不正确(“数组”和第一个“dict”元素未关闭)。您可能需要再次检查它是否正确。谢谢您的回复,我还需要计算通过和失败的测试数。预期o/p总测试通过=1总测试失败=1我将此作为练习留给读者。。。但是无论如何,我现在已经修改了我的答案,以显示总行数。嗨,蒂姆,请参考主要部分中的预期结果。我已经更新了我的答案,但将来在回答一个问题后,您能否小心修改您的预期输出。如果需要,问一个新问题没有什么错。谢谢。因为我在“添加评论”部分没有更多的空间,所以在主部分进行了更新。非常感谢您的解决方案。