代码之家  ›  专栏  ›  技术社区  ›  StevenWilkins

XSLT-如何拆分父级的子级

  •  2
  • StevenWilkins  · 技术社区  · 14 年前

    我的xml结构包含一个作为证书和课程父级的程序。我想分割结构,创建一个独立的证书和课程列表,而不需要公共程序父程序。原始结构为:

    <root>
      <program>
        <program-name>Math</program-name>
        <certificate>...</certificate> <!-- There can 0 or more of these -->
        <course>...</course> <!-- There can 0 or more of these -->
      </program>
      <program>
        ...
      </program>
    </root>
    

    输出应该如下所示:

    <root>
       <program-courses>
         <program>
           <program-name>Math</program-name>
           <course/> <!-- There can 0 or more of these -->
         </program>
         ...
       </program-courses>
       <program-certificates>
         <program>
           <program-name>Math</program-name>
           <certificate/> <!-- There can 0 or more of these -->
         </program>
         ...
       </program-certificates>
    </root>
    

    更新 :使用Paul关于使用模式的建议回答这就是xslt的相关部分:

    <xsl:template match="root">
            <xsl:element name="root">
                <xsl:element name="program-courses">
                    <xsl:apply-templates select="root/program-area" mode="course"/>
                </xsl:element>
                <xsl:element name="program-certificates">
                    <xsl:apply-templates select="root/program-area" mode="certificate"/>
                </xsl:element>
            </xsl:element>           
        </xsl:template>
    
        <xsl:template match="program-area" mode="course">
            <xsl:element name="program-area">
               <!-- Get the name here -->
                <xsl:element name="course">
                    <xsl:apply-templates select="course"/>
                </xsl:element>
            </xsl:element>
        </xsl:template>
    
        <xsl:template match="program-area" mode="certificate">
            <xsl:element name="program-area">
               <!-- Get the name here -->
                <xsl:element name="course">
                    <xsl:apply-templates select="certificate"/>
                </xsl:element>
            </xsl:element>
        </xsl:template>
    

    请注意,此解决方案与实际解决方案相比有所减少,因此它可能无法像对原始输入那样工作。

    2 回复  |  直到 14 年前
        1
  •  1
  •   Paul Butcher    14 年前
    1. 选择程序 elements ,你可以使用 @mode (开) apply-templates 以及相应的 template )区分您是否在 program-courses program-certificates

    2. root ,您可以选择 program/course program/certificate 生成输出 program .

    3. ,你可以使用 for-each select="program" 对于打算输出的部分 课程 只提取 program-name course element ,并在输出的部分执行相应的提取 课程证书 .

        2
  •  1
  •   user357812user357812    14 年前

    此样式表:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="node()|@*" name="identity">
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="program">
            <xsl:apply-templates select="course[1]|certificate[1]"/>
        </xsl:template>
        <xsl:template match="course[1]">
            <program-courses>
                <program>
                    <xsl:apply-templates select="../*[not(self::certificate)]"
                                         mode="copy"/>
                </program>
            </program-courses>
        </xsl:template>
        <xsl:template match="certificate[1]">
            <program-certificates>
                <program>
                    <xsl:apply-templates select="../*[not(self::course)]"
                                         mode="copy"/>
                </program>
            </program-certificates>
        </xsl:template>
        <xsl:template match="node()" mode="copy">
            <xsl:call-template name="identity"/>
        </xsl:template>
    </xsl:stylesheet>
    

    输出:

    <root>
        <program-certificates>
            <program>
                <program-name>Math</program-name>
                <certificate>...</certificate>
            </program>
        </program-certificates>
        <program-courses>
            <program>
                <program-name>Math</program-name>
                <course>...</course>
            </program>
        </program-courses>
    </root>
    

    编辑 :如果您想要更多的“推送风格”,如发布的解决方案:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="node()|@*" name="identity">
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="node()" mode="certificate">
            <xsl:call-template name="identity"/>
        </xsl:template>
        <xsl:template match="node()" mode="course">
            <xsl:call-template name="identity"/>
        </xsl:template>
        <xsl:template match="program">
            <program-courses>
                <program>
                    <xsl:apply-templates mode="course"/>
                </program>
            </program-courses>
            <program-certificates>
                <program>
                    <xsl:apply-templates mode="certificate"/>
                </program>
            </program-certificates>
        </xsl:template>
        <xsl:template match="course" mode="certificate"/>
        <xsl:template match="certificate" mode="course"/>
    </xsl:stylesheet>