如何使用xslt在现有xml中附加新节点

时间:2011-11-30 09:22:38

标签: xml xslt

我有以下xml:

<?xml version="1.0"?>
<navigation path="/english">
  <resources>
    <Copyright>© 2009 mysite. All Rights Reserved.</Copyright>
  </resources>
  <node title="010. Terms and Conditions" id="tcm:233-242834-64" url="termscondition.aspx" compTitle="Terms and Conditions"/>
    <node title="Root" id="tcm:233-38288-4" url="/">
        <node title="040. Skywards" id="tcm:233-38448-4" url="/Skywards/skywards.aspx" indexpage="tcm:233-192262-64" compTitle="Skywards" imageSrcOn="/english/Images/skywards_on_tcm233-191728.gif" imageSrcOff="/english/Images/skywards_off_tcm233-191727.gif" imageSrcSelected="/english/Images/skywards_sel_tcm233-191730.gif" imageSrcSelectedOn="/english/Images/skywards_on2_tcm233-191729.gif" accessKey="S" Group="yes">
          <node title="010. Membership Tiers" id="tcm:233-38882-4" url="/Skywards/membership_tiers/membership_tiers.aspx" indexpage="tcm:233-194317-64" compTitle="Membership Tiers"/>
          <node title="020. Earning Miles" id="tcm:233-38883-4" url="/Skywards/earning_miles/earning_miles.aspx" indexpage="tcm:233-194318-64" compTitle="Earning Miles"/>
          <node title="030. Travel Rewards" id="tcm:233-38884-4" url="/Skywards/travel_rewards/travel_rewards.aspx" indexpage="tcm:233-194320-64" compTitle="Travel Rewards" Group="yes"/>
          <node title="040. Journey Management Tools" id="tcm:233-38885-4" url="/Skywards/journey_management_tools/journey_management.aspx" indexpage="tcm:233-194322-64" compTitle="Journey Management "/>
          <node title="050. Personal Travel Coordinator" id="tcm:233-38886-4" url="/Skywards/personal_travel_coordinator/personal_travel_coordinator.aspx" indexpage="tcm:233-194324-64" compTitle="Personal Travel Coordinator"/>
          <node title="060. Skysurfers" id="tcm:233-38887-4" url="/Skywards/skysurfers/skysurfers.aspx" indexpage="tcm:233-194326-64" compTitle="Skysurfers" Group="yes"/>
        </node>
    </node>
    <node title="footer">
        <node title="F010. 000. Sitemap" id="tcm:233-192374-64" url="/sitetools/sitemap.aspx" accessKey="4" compTitle="Sitemap"/>
        <node title="F060. Accessibility" id="tcm:233-192369-64" url="/sitetools/accessibility.aspx" compTitle="Accessibility Statement"/>
        <node title="F030. Operational Updates" id="tcm:233-192370-64" url="/sitetools/operational_updates.aspx" compTitle="Operational Updates"/>
        <node title="F050. Privacy Policy" id="tcm:233-192371-64" url="/sitetools/privacy_policy.aspx" compTitle="Privacy Policy"/>
        <node title="F040. Terms &amp; Conditions" id="tcm:233-192449-64" url="/sitetools/terms_and_conditions.aspx" compTitle="Terms &amp; Conditions"/>
    </node>
</navigation>

现在我想编写一个XSLT,它将检查Group =“Yes”并将呈现以下输出的XML:

<?xml version="1.0"?>
<navigation path="/english">
  <resources>
    <Copyright>© 2009 mysite. All Rights Reserved.</Copyright>
  </resources>
  <node title="010. Terms and Conditions" id="tcm:233-242834-64" url="termscondition.aspx" compTitle="Terms and Conditions"/>
    <node title="Root" id="tcm:233-38288-4" url="/">
        <node title="040. Skywards" id="tcm:233-38448-4" url="/Skywards/skywards.aspx" indexpage="tcm:233-192262-64" compTitle="Skywards" imageSrcOn="/english/Images/skywards_on_tcm233-191728.gif" imageSrcOff="/english/Images/skywards_off_tcm233-191727.gif" imageSrcSelected="/english/Images/skywards_sel_tcm233-191730.gif" imageSrcSelectedOn="/english/Images/skywards_on2_tcm233-191729.gif" accessKey="S" Group="yes">
          <node title="010. Membership Tiers" id="tcm:233-38882-4" url="/Skywards/membership_tiers/membership_tiers.aspx" indexpage="tcm:233-194317-64" compTitle="Membership Tiers"/>
          <node title="020. Earning Miles" id="tcm:233-38883-4" url="/Skywards/earning_miles/earning_miles.aspx" indexpage="tcm:233-194318-64" compTitle="Earning Miles"/>
          <node title="040. Journey Management Tools" id="tcm:233-38885-4" url="/Skywards/journey_management_tools/journey_management.aspx" indexpage="tcm:233-194322-64" compTitle="Journey Management "/>
          <node title="050. Personal Travel Coordinator" id="tcm:233-38886-4" url="/Skywards/personal_travel_coordinator/personal_travel_coordinator.aspx" indexpage="tcm:233-194324-64" compTitle="Personal Travel Coordinator"/>
        </node>
    </node>
    <node title="footer">
        <node title="F010. 000. Sitemap" id="tcm:233-192374-64" url="/sitetools/sitemap.aspx" accessKey="4" compTitle="Sitemap"/>
        <node title="F060. Accessibility" id="tcm:233-192369-64" url="/sitetools/accessibility.aspx" compTitle="Accessibility Statement"/>
        <node title="F030. Operational Updates" id="tcm:233-192370-64" url="/sitetools/operational_updates.aspx" compTitle="Operational Updates"/>
        <node title="F050. Privacy Policy" id="tcm:233-192371-64" url="/sitetools/privacy_policy.aspx" compTitle="Privacy Policy"/>
        <node title="F040. Terms &amp; Conditions" id="tcm:233-192449-64" url="/sitetools/terms_and_conditions.aspx" compTitle="Terms &amp; Conditions"/>
    </node>
    <node title="Group">
        <node>
            <node title="040. Skywards" id="tcm:233-38448-4" url="/Skywards/skywards.aspx" indexpage="tcm:233-192262-64" compTitle="Skywards" imageSrcOn="/english/Images/skywards_on_tcm233-191728.gif" imageSrcOff="/english/Images/skywards_off_tcm233-191727.gif" imageSrcSelected="/english/Images/skywards_sel_tcm233-191730.gif" imageSrcSelectedOn="/english/Images/skywards_on2_tcm233-191729.gif" accessKey="S">
                <node title="030. Travel Rewards" id="tcm:233-38884-4" url="/Skywards/travel_rewards/travel_rewards.aspx" indexpage="tcm:233-194320-64" compTitle="Travel Rewards" Group="yes"/>            
                <node title="060. Skysurfers" id="tcm:233-38887-4" url="/Skywards/skysurfers/skysurfers.aspx" indexpage="tcm:233-194326-64" compTitle="Skysurfers" Group="yes"/>
            </node>
        </node> 
    </node>     
</navigation>   

在上面输出的xml中,您可以看到添加了标题组的额外节点以及 Group =“yes”的子节点从顶部删除并在下面添加。< / p>

请建议!!

2 个答案:

答案 0 :(得分:1)

我将尝试使用以下解决方案进行上述问题:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    <xsl:template match="*">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()"/>
            <xsl:if test="self::navigation">
                <node title="Group">
                    <node>
                        <xsl:apply-templates select="node()" mode="group"></xsl:apply-templates>
                    </node>
                </node>
            </xsl:if>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="node" mode="group">
        <xsl:choose>
            <xsl:when test="@Group = 'yes'">
                <xsl:copy>
                    <xsl:copy-of select="@*"/>
                    <xsl:apply-templates select="node()" mode="group"/>
                </xsl:copy>            
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates select="node()" mode="group"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="*" mode="group"/>
</xsl:stylesheet>

答案 1 :(得分:0)

XSLT 2.0解决方案。我不确定我是否完全理解了确切的目标,因此它适用于这个具体案例,但如果我误解了一些要求,则可能需要进行调整:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output indent="yes"></xsl:output>
    <xsl:template match="/">
        <xsl:apply-templates></xsl:apply-templates>
    </xsl:template>
    <xsl:template match="*|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="node[@Group='yes' and not(exists(node()))]"/>
    <xsl:template match="node[@Group='yes' and exists(node())]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:copy-of select="node[not(@Group='yes')]"/>
        </xsl:copy>        
    </xsl:template>
    <xsl:template match="node[@Group='yes' and exists(node())]" mode="groupOnly">
        <xsl:copy>
            <xsl:apply-templates select="@*[not(name()='Group')]"/>
            <xsl:copy-of select="node[@Group='yes']"/>
        </xsl:copy>        
    </xsl:template>
    <xsl:template match="navigation">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
            <node title="Group">
                <node>
                    <xsl:apply-templates select="//node[@Group='yes' and exists(node())]" mode="groupOnly"/>                                    
                </node>
            </node>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

我们的想法是逐个整个树,这是match="*|@*"模板的业务,然后为每个需要它的元素提供特定的模板。

然后我针对不同的情况使用不同的模式:预先存在的节点中的节点副本的默认模式。我在新节点元素中复制的节点的groupOnly模式。