如何使用XSLT在特定标记之后插入XML标记?

时间:2017-11-06 22:25:18

标签: xml xslt xpath

您好 - 我帮助您使用XSLT转换以下输入XML



<?xml version="1.0" encoding="UTF-8"?>
<Employee>
	<Summary>
		<Employee_ID>12345</Employee_ID>
		<Name>Mel Gibson</Name>
	</Summary>
	<Personal>
		<First_Name>Mel</First_Name>
		<Middle_Name>Samuel</Middle_Name>
		<Gender>Male</Gender>
	</Personal>
	<Status>
		<Active>Yes</Active>
		<Base_Location>Boston</Base_Location>
	</Status>
	<Summary_Information>
		<Location>California</Location>
		<Last_Formatted_Name>Samuel Gibson</Last_Formatted_Name>
	</Summary_Information>
</Employee>
&#13;
&#13;
&#13;

转换上述XML的要求是:

如果输入XML中不存在Last_Name,则应在First_Name节点之后立即创建一个节点Last_Name,并且应该保留Last_Formatted_Name的值

输出应如下所示。请注意,在删除First_Name和Last_Formatted_Name节点后立即创建Last_Name节点。

&#13;
&#13;
<?xml version="1.0" encoding="UTF-8"?>
<Employee>
	<Summary>
		<Employee_ID>12345</Employee_ID>
		<Name>Mel Gibson</Name>
	</Summary>
	<Personal>
		<First_Name>Mel</First_Name>
		<Last_Name>Samuel Gibson</Last_Name>
		<Middle_Name>Samuel</Middle_Name>
		<Gender>Male</Gender>
	</Personal>
	<Status>
		<Active>Yes</Active>
		<Base_Location>Boston</Base_Location>
	</Status>
	<Summary_Information>
		<Location>California</Location>
	</Summary_Information>
</Employee>
&#13;
&#13;
&#13;

我已经编写了以下XSLT(在另一个stackoverflow帖子的帮助下)。但是,Last_Name将作为“个人”下的最后一个标记插入,其中“Last_Name”应插入“First_Name”标记之后。

&#13;
&#13;
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*" />

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

    <!-- modifies the value of <Last_Name> if it exists -->
    <xsl:template match="Last_Name">
        <xsl:copy>
            <xsl:value-of select="../../Summary_Information/Last_Formatted_Name" />
        </xsl:copy>
    </xsl:template>

    <!-- if <Last_Name> does not exist, creates a last name with the appropriate value -->
    <xsl:template match="Personal[not(Last_Name)]">
        <xsl:copy>
            <xsl:apply-templates />
            <Last_Name>
                <xsl:value-of select="../Summary_Information/Last_Formatted_Name" />
            </Last_Name>
        </xsl:copy>
    </xsl:template>

    <!-- removes the node -->
    <xsl:template match="Last_Formatted_Name" />
</xsl:stylesheet>
&#13;
&#13;
&#13;

通过上面的XSLT,我得到了以下结果。我应该如何更改我的XSLT以在First_Name标记之后插入Last_Name。

&#13;
&#13;
<?xml version="1.0" encoding="UTF-8"?>
<Employee>
	<Summary>
		<Employee_ID>12345</Employee_ID>
		<Name>Mel Gibson</Name>
	</Summary>
	<Personal>
		<First_Name>Mel</First_Name>
		<Middle_Name>Samuel</Middle_Name>
		<Gender>Male</Gender>
		<Last_Name>Samuel Gibson</Last_Name>
	</Personal>
	<Status>
		<Active>Yes</Active>
		<Base_Location>Boston</Base_Location>
	</Status>
	<Summary_Information>
		<Location>California</Location>
	</Summary_Information>
</Employee>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

您可以将模板应用于First_Name,创建新的Last_Name,然后将模板应用于其他所有模板。

示例...

<xsl:template match="Personal[not(Last_Name)]">
  <xsl:copy>
    <xsl:apply-templates select="First_Name"/>
    <Last_Name>
      <xsl:value-of select="../Summary_Information/Last_Formatted_Name" />
    </Last_Name>
    <xsl:apply-templates select="*[not(self::First_Name)]"/>
  </xsl:copy>
</xsl:template>