在xslt中的祖先节点中插入元素

时间:2015-02-17 09:15:45

标签: xslt

如果条件在后代元素中为真,我想在祖先元素中插入一个元素。在xml下面我想在“part”元素中插入一个新元素“blue”,这是后代元素“patternCode”的值“。只有当”patternCode“元素具有相同的值”blue“时才应插入元素 注意:xml中有2个patternCode元素应该进行比较

<Request >
    <Part>
        <Lines>
            <Entry>
                <entity>
                    <Cover>
                        <Entry>
                            <Terms>
                                <Entry>
                                    <DisplayValue/>
                                    <PatternCode>Blue</PatternCode>
                                    <ValueTypeName>bit</ValueTypeName>
                                </Entry>
                            </Terms>
                            <Pattern>
                                <Description>white</Description>
                                <Name>white</Name>
                            </Pattern>
                            <PatternCode>Blue</PatternCode>
                            <PublicID>pc</PublicID>
                        </Entry>
                    </Cover>
                    <Locations>
                        <!-- other data-->
                    </Locations>
                </entity>
            </Entry>
        </Lines>
    </Part>
</Request>

预期产出

<Request >
    <Part>
     <Blue>  <Blue>
        <Lines>
            <Entry>
                <entity>
                    <Cover>
                        <Entry>
                            <Terms>
                                <Entry>
                                    <DisplayValue/>
                                    <PatternCode>Blue</PatternCode>
                                    <ValueTypeName>bit</ValueTypeName>
                                </Entry>
                            </Terms>
                            <Pattern>
                                <Description>white</Description>
                                <Name>white</Name>
                            </Pattern>
                            <PatternCode>Blue</PatternCode>
                            <PublicID>pc</PublicID>
                        </Entry>
                    </Cover>
                    <Locations>
                        <!-- other data-->
                    </Locations>
                </entity>
            </Entry>
        </Lines>
    </Part>
</Request>

我尝试了什么

 <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
    <xsl:strip-space elements="*" />

    <xsl:template match="Request/Part/Lines/Entry/entity/Cover" >
    <xsl:copy>
       <xsl:for-each select="Entry">
            <xsl:copy>
                   <xsl:apply-templates select="@* | node()" />
            </xsl:copy>
        <xsl:variable name="x">
        <xsl:value-of select="PatternCode"/>
        </xsl:variable>

        <xsl:for-each select="Terms/Entry">           
           <xsl:variable name="y">
            <xsl:value-of select="PatternCode"/>
              </xsl:variable>
                   <xsl:if test="$x=$y">
                      <xsl:call-template name="compute" >
                               <xsl:with-param name="value" select="$y"/>
                      </xsl:call-template>
                   </xsl:if>
               </xsl:for-each>
        </xsl:for-each>
    </xsl:copy>
      </xsl:template>

    <xsl:template name="compute" >
    <xsl:param name="value"/>
      <xsl:for-each select="Part">
         <xsl:element name="{$value}"></xsl:element> 
    <xsl:for-each >                 
    </xsl:template>

    </xsl:stylesheet>

2 个答案:

答案 0 :(得分:0)

你应该采取相反的方法:

<template match="part">
 <xsl:if test="descendant::cover/entry/terms/entry/patterncode = descendant::cover/entry/patterncode"> 
insert the <blue> node here

修改您当前使用的元素要容易得多。

答案 1 :(得分:0)

我相信这应该做到:

<强> XSLT1.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Part">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:if test="count(.//PatterCode) = count(.//PatterCode[. = (current()//PatternCode)[1]])">
                <Blue/>
            </xsl:if>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

我认为XSLT2.0会让它变得更加容易和高效:

<强> XSLT2.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Part[count(.//PatterCode) = count(.//PatterCode[. = (current()//PatternCode)[1]])]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <Blue/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>