xsl抓取节点项匹配兄弟项

时间:2018-03-21 06:01:05

标签: xml xslt

我得到了以下XML:

 if ($course) 

        $users_query="SELECT o.title as course_title,u.*,u.usr_id,o.obj_id FROM object_data o,usr_data u,obj_members rn WHERE o.obj_id=rn.obj_id AND u.usr_id=rn.usr_id AND o.type='crs'  AND o.obj_id=$course";
    //dd($users_query);


    $user_records = $this->base_model->executeSelectQuery($users_query);
    //dd($user_records);
    $final_data = [];

    foreach($user_records as $user)
    {
        if(!$course)
            continue;
        $user_course_query = "SELECT *, (select obj_id FROM `object_reference` obr WHERE obr.ref_id = t.child) as final_reference FROM object_data o,object_reference r,tree t  WHERE o.obj_id=r.obj_id AND t.parent=r.ref_id AND o.obj_id=$course";

               $user_course_query =
    "
              SELECT *,(select obj_id FROM object_reference f WHERE f.ref_id = e.child and f.ref_id=e.child) as final_reference FROM object_data a JOIN object_reference b ON a.obj_id = b.obj_id JOIN tree c ON b.ref_id = c.parent JOIN object_reference d ON c.child = d.ref_id JOIN tree e ON d.ref_id = e.parent JOIN object_reference f ON e.child = f.ref_id JOIN object_data g ON f.obj_id = g.obj_id JOIN tst_tests s ON g.obj_id=s.obj_fi JOIN tst_active t ON s.test_id=t.test_fi JOIN usr_data u ON u.usr_id=t.user_fi and u.usr_id=$user->usr_id and  a.obj_id=$course GROUP by a.obj_id" ;
        // dd($user_course_query);
        //$this->db->escape($user_course_query);
            $user_course_records = $this->base_model->executeSelectQuery($user_course_query);
    // dd($user_course_records);

        foreach($user_course_records as $course_data)
        { 
            $final_reference=$course_data->final_reference;

            $user_tests_query = "SELECT u.firstname,o.*,ta.*,tpr.workingtime,tcr.mark_official,(tcr.reached_points/tcr.max_points)*100 as result,v.value FROM usr_data u,object_data o,tst_active ta,tst_tests tt ,tst_pass_result tpr, tst_result_cache tcr,udf_text v WHERE u.usr_id=ta.user_fi AND tt.obj_fi=o.obj_id AND v.usr_id=u.usr_id AND ta.test_fi=tt.test_id  AND ta.active_id=tpr.active_fi AND tcr.active_fi=ta.active_id AND v.field_id='2'   AND u.usr_id=$user->usr_id AND  o.obj_id = $final_reference ".$date_condition;


        $user_tests = $this->base_model->executeSelectQuery($user_tests_query);

            foreach($user_tests as $test)
            {

                $dta['usr_id']      = $user->usr_id;
                $dta['firstname']       = $user->firstname;
                $dta['email']           = $user->email;
                $dta['matriculation']   = $user->matriculation;
                $dta['approve_date']    = $user->approve_date;
                $dta['department']  = $user->department;


                $final_data[] = $dta;
            }
        }

    }
    $data['records'] = $final_data;

以及以下XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<batch>
  <batchnummer>782</batchnummer>
  <continueonerror>true</continueonerror>
  <metafileversion>1.0</metafileversion>
<documentset>
  <naam></naam>
  <type></type>
  <subsets>
<subset>
  <staple>true</staple>
  <subdocuments>
    <subdocument>
      <document>thr6UhEw5bER6Cjt8uKOCg</document>
      <stamp></stamp>
      <mediatype>Briefpapier</mediatype>
      <duplex>false</duplex>
    </subdocument>
    <subdocument>
      <document>thr6UhEw5bER6Cjt8uRUiA</document>
      <stamp></stamp>
      <mediatype>Briefpapier</mediatype>
      <duplex>false</duplex>
    </subdocument>
  </subdocuments>
</subset>
<subset>
  <staple>true</staple>
  <subdocuments>
    <subdocument>
      <document>thr6UhEw5bER6Cjt8uSxgA</document>
      <stamp></stamp>
      <mediatype>Blanco</mediatype>
      <duplex>false</duplex>
    </subdocument>
    <subdocument>
      <document>thr6UhEw5bER6Cjt8uSCCg</document>
      <stamp></stamp>
      <mediatype>Blanco</mediatype>
      <duplex>false</duplex>
    </subdocument>
    <subdocument>
      <document>thr6UhEw5bER6Cjt8uKOCg</document>
      <stamp></stamp>
      <mediatype>Briefpapier</mediatype>
      <duplex>false</duplex>
    </subdocument>
    <subdocument>
      <document>thr6UhEw5bER6Cjt8uUH-A</document>
      <stamp></stamp>
      <mediatype>Briefpapier</mediatype>
      <duplex>false</duplex>
    </subdocument>
  </subdocuments>
</subset>
</subsets>
  <documenten>
    <document>
      <naam>00000782_000001.rtf</naam>
      <code>thr6UhEw5bER6Cjt8uKOCg</code>
      <duplex>false</duplex>
      <type>RTF</type>
    </document>
    <document>
      <naam>00000782_000002.rtf</naam>
      <code>thr6UhEw5bER6Cjt8uRUiA</code>
      <duplex>false</duplex>
      <type>RTF</type>
    </document>
    <document>
      <naam>00000782_000003.rtf</naam>
      <code>thr6UhEw5bER6Cjt8uSCCg</code>
      <duplex>false</duplex>
      <type>RTF</type>
    </document>
    <document>
      <naam>00000782_000004.rtf</naam>
      <code>thr6UhEw5bER6Cjt8uSxgA</code>
      <duplex>false</duplex>
      <type>RTF</type>
    </document>
    <document>
      <naam>00000782_000005.rtf</naam>
      <code>thr6UhEw5bER6Cjt8uUH-A</code>
      <duplex>false</duplex>
      <type>RTF</type>
    </document>
  </documenten>
</documentset>
  <batchcontrole>
    <cntset>29</cntset>
    <cntdoc>75</cntdoc>
    <cntsub>58</cntsub>
  </batchcontrole>
</batch>

不知何故,我无法动态选择“naam”节点。当我做一个特定的xpath选择示例

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:for-each select="//subsets/subset">
        <subset>
            <xsl:for-each select="subdocuments/subdocument">
                <documentname><xsl:value-of select="./document"/></documentname>
                <documentcode><xsl:value-of select="//document/naam[../code='./document']/text()"/></documentcode>
            </xsl:for-each>
        </subset>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

它工作正常,但只要我用//document/naam[../code='thr6UhEw5bER6Cjt8uSCCg']/text() current()/document替换它就会再检索任何东西......

当我使用静态xpath时,它可以正常工作并检索每个foreach循环的信息。

如何在de xslt中动态生成xpath?

目前正试图找出xslt虽然我无法让它正常工作......

2 个答案:

答案 0 :(得分:1)

<xsl:for-each select="subdocuments/subdocument">内,您需要将document的值存储在变量中

<xsl:variable name="doc" select="document" />

使用此变量的值与code的值进行比较,并提取所需的值。

<xsl:value-of select="//document[code=$doc]/naam" />

提取值的另一个选项是使用ancestor轴。

<xsl:value-of select="ancestor::documentset/documenten/document[code=$doc]/naam" />

以下是更新的模板

<xsl:template match="/">
    <xsl:for-each select="//subsets/subset">
        <subset>
            <xsl:for-each select="subdocuments/subdocument">
                <xsl:variable name="doc" select="document" />
                <documentname>
                    <xsl:value-of select="$doc" />
                </documentname>
                <documentcode>
                    <xsl:value-of select="//document[code=$doc]/naam" />
                </documentcode>
            </xsl:for-each>
        </subset>
    </xsl:for-each>
</xsl:template>

这给出了以下输出

<subset>
    <documentname>thr6UhEw5bER6Cjt8uKOCg</documentname>
    <documentcode>00000782_000001.rtf</documentcode>
    <documentname>thr6UhEw5bER6Cjt8uRUiA</documentname>
    <documentcode>00000782_000002.rtf</documentcode>
</subset>
<subset>
    <documentname>thr6UhEw5bER6Cjt8uSxgA</documentname>
    <documentcode>00000782_000004.rtf</documentcode>
    <documentname>thr6UhEw5bER6Cjt8uSCCg</documentname>
    <documentcode>00000782_000003.rtf</documentcode>
    <documentname>thr6UhEw5bER6Cjt8uKOCg</documentname>
    <documentcode>00000782_000001.rtf</documentcode>
    <documentname>thr6UhEw5bER6Cjt8uUH-A</documentname>
    <documentcode>00000782_000005.rtf</documentcode>
</subset>

答案 1 :(得分:1)

当前表达式的问题在于您将./document括在了撇号中,这使得它成为字符串文字,而不是表达式。

应该是这样的(你也需要使用current().代表上下文节点,current()当前节点。参见Current node vs. Context node in XSLT/XPath?

<xsl:value-of select="//document/naam[../code=current()/document]/text()"/>

或者,稍微简单一点,这......

<xsl:value-of select="//document[code=current()/document]/naam"/>

更好的是,使用密钥查找文档。

<xsl:key name="docs" match="document[code]" use="code" />

然后表达式就变成了......

<xsl:value-of select="key('docs', document)/naam"/>

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />

<xsl:key name="docs" match="document[code]" use="code" />

<xsl:template match="/">
    <xsl:for-each select="//subsets/subset">
        <subset>
            <xsl:for-each select="subdocuments/subdocument">
                <documentname><xsl:value-of select="document"/></documentname>
                <documentcode><xsl:value-of select="key('docs', document)/naam"/></documentcode>
            </xsl:for-each>
        </subset>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>