根据节点值转换xml

时间:2017-05-04 13:15:46

标签: xslt

我的要求稍微复杂一点。我有以下输入xml:

<results>
   <row>
      <CASEID>C1</CASEID>
      <CASEBA>MEDICAID</CASEBA>
      <ISSUEID>I1</ISSUEID>
      <ISSUEBA>MEDICAID</ISSUEBA>
      <OBJECTID>1</OBJECTID>
   </row>
   <row>
      <CASEID>C1</CASEID>
      <CASEBA>MEDICAID</CASEBA>
      <ISSUEID>I2</ISSUEID>
      <ISSUEBA>MEDICAID</ISSUEBA>
      <OBJECTID>2</OBJECTID>
   </row>
   <row>
      <CASEID>C1</CASEID>
      <CASEBA>MEDICAID</CASEBA>
      <ISSUEID>I1</ISSUEID>
      <ISSUEBA>MEDICAID</ISSUEBA>
      <OBJECTID>extra</OBJECTID>
   </row>
   <row>
      <CASEID>C2</CASEID>
      <CASEBA>MEDICAID</CASEBA>
      <ISSUEID>I3</ISSUEID>
      <ISSUEBA>MEDICAID</ISSUEBA>
      <OBJECTID>3</OBJECTID>
   </row>
</results>

我必须按照以下条件使用XSLT将上述xml转换为更简单的xml:

1)第一个目标是将新<CASEID>标记下的值相同的所有<CASE><CASEBA>节点一起移动。

例如:

<CASE>
   <CASEID>C1</CASEID>
   <CASEBA>MEDICAID</CASEBA>
</CASE>

2)列出所有<ISSUEID>&amp; <ISSUEBA> <CASEID>在不同的<row>中相等的所有<ISSUE>&amp; <CASE>最近创建的 <CASE> <CASEID>C1</CASEID> <CASEBA>MEDICAID</CASEBA> <ISSUE> <ISSUEID>I1</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> </ISSUE> <ISSUE> <ISSUEID>I2</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> </ISSUE> </CASE> 代码中的新代码<OBJECTID>

例如:

<ISSUEID>

3)列出<row><SOURCE><ISSUE>&#39}中相同的所有<CASE>&#39},并将它们移到新的<CASE> <CASEID>C1</CASEID> <CASEBA>MEDICAID</CASEBA> <ISSUE> <ISSUEID>I1</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> <SOURCE> <OBJECTID>1</OBJECTID> </SOURCE> <SOURCE> <OBJECTID>extra</OBJECTID> </SOURCE> </ISSUE> <ISSUE> <ISSUEID>I2</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> <SOURCE> <OBJECTID>2</OBJECTID> </SOURCE> </ISSUE> </CASE> <results> <CASE> <CASEID>C1</CASEID> <CASEBA>MEDICAID</CASEBA> <ISSUE> <ISSUEID>I1</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> <SOURCE> <OBJECTID>1</OBJECTID> </SOURCE> <SOURCE> <OBJECTID>extra</OBJECTID> </SOURCE> </ISSUE> <ISSUE> <ISSUEID>I2</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> <SOURCE> <OBJECTID>2</OBJECTID> </SOURCE> </ISSUE> </CASE> <CASE> <CASEID>C2</CASEID> <CASEBA>MEDICAID</CASEBA> <ISSUE> <ISSUEID>I3</ISSUEID> <ISSUEBA>MEDICAID</ISSUEBA> <SOURCE> <OBJECTID>3</OBJECTID> </SOURCE> </ISSUE> </CASE> </results> 标记内的$redis = new RedisHandler(); $redis2 = new RedisHandler('redis2'); //this one gets first $redis connection 标记肯定属于class RedisHandler { static $db = null; public function __construct($redisdb = 'redis') { // opening db connection return self::connect($redisdb); } static public function connect($redisdb) { global $config; if (self::$db === null) { try { $redisClient = new Redis(); $redisClient -> connect($config[$redisdb]['host'], $config[$redisdb]['port'], $config[$redisdb]['timeout'], null, $config[$redisdb]['reservedInterval'] ); $redisClient->setOption(Redis::OPT_READ_TIMEOUT, 100); if (!$redisClient) { throw new Exception("Can't connect to Redis"); } } catch (Exception $e) { die('Failed to connect to Redis '.$e->getMessage()); } self::$db = $redisClient; return self::$db; //return $m; } else { // return self::$db; return self::$db; } } } 。 例如:

#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>  

最终输出xml应如下所示:

AVPlayerViewController * _moviePlayer1 = [[AVPlayerViewController alloc] init];
    _moviePlayer1.player = [AVPlayer playerWithURL:_img.contentURL];

    [self presentViewController:_moviePlayer1 animated:YES completion:^{
        [_moviePlayer1.player play];
    }];  

如果我没有正确解释我的要求,请原谅我。如果您需要任何其他信息,请询问我。如果有人帮助我,真的很棒。

1 个答案:

答案 0 :(得分:1)

使用XSLT 1,您必须使用一种称为“Muenchian分组”的技术,事情会变得有点复杂。幸运的是,使用XSLT 2,您可以使用<xsl:for-each-group>元素和current-group()函数。以下样式表生成给定输入所需的确切输出:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:output method="xml" indent="yes" />

    <xsl:key name="caseID" match="row" use="CASEID" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/results">
        <results>
            <xsl:for-each-group select="row" group-by="CASEID">
                <xsl:call-template name="handleCase" />
            </xsl:for-each-group>
        </results>
    </xsl:template>

    <xsl:template name="handleCase"> 
        <CASE>
            <xsl:copy-of select="CASEID" />
            <xsl:copy-of select="CASEBA" />
            <xsl:for-each-group select="current-group()" group-by="ISSUEID">
                <xsl:call-template name="handleIssue" />
            </xsl:for-each-group>
        </CASE>
    </xsl:template>

    <xsl:template name="handleIssue"> 
        <ISSUE>
            <xsl:copy-of select="ISSUEID" />
            <xsl:copy-of select="ISSUEBA" />
            <xsl:apply-templates select="current-group()/OBJECTID" />
        </ISSUE>
    </xsl:template>

    <xsl:template match="OBJECTID">
        <SOURCE>
            <xsl:copy-of select="." />
        </SOURCE>
    </xsl:template>

</xsl:transform>

你可以嵌套整个东西,但为了保持可读性,我把它分成几个命名的模板。幸运的是,在调用另一个模板时,会保留当前的组上下文,以便您可以在该组中进一步分组。