1

这是我的源文件的样子:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<book>
    <mbean code="org.book.mybooks"  name="mycompany.props.jndi:name=mybookprops">   
        <attribute name="bookprops">
            abc.mybook.onebook=@Value@
            def.mybook.twobook=@Value@
            ghi.myebook.threebook=@Value@
        </attribute>
    </mbean>
    <book>
        <mbean code="org.book.mybooks"  name="mycompany.props.jndi:name=mybookprops">   
            <attribute name="bookprops">
            abc.mybook.onebook=@New_Value@
            def.mybook.twobook=@New_Value@
            ghi.myebook.fourbook=@Value@

            </attribute>
        </mbean>
    </book>
</book>

我希望将两个属性合并为一个,并使用新变量@New_Value@复制所有匹配的行,并将所有其他不匹配的行复制到文件末尾。

这个问题与我之前发布的基于属性值使用 xslt 合并父属性和子属性的问题非常相似,唯一的区别是 XML 文件中内容的格式。

基于上述 URL 中提供的解决方案,我调整了我的 xsl 以使用这个新的 XML 文件,这里是 xsl 文件:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:jndi="urn:jboss:jndi-binding-service:1.0"  >
    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" /> 
    <xsl:template match="book/book"> 
        <book>
            <mbean code="org.book.mybooks" name="mycompany.props.jndi:name=mybookprops">    
                <attribute name="bookprops">
                    <xsl:copy-of select="mbean/attribute/node()"/>
                    <xsl:call-template name="Mbean">
                        <xsl:with-param name="bindings" select="book/mbean/attribute"/>
                    </xsl:call-template> 
                </attribute>
            </mbean>
        </book>
    </xsl:template>  

    <xsl:template name="Mbean">
        <xsl:param name="bindings"/>
        <xsl:for-each select="/book/mbean/attribute/node()">
            <xsl:variable name="currentBinding" select="self::node()"/>  
            <xsl:if test="not(node()[. = $bindings])">
                <xsl:copy-of select="self::node()"/>
            </xsl:if>                        
        </xsl:for-each>
    </xsl:template>
    <xsl:template match="text()"/>
</xsl:stylesheet>

但不知何故我无法得到预期的结果,以下是我正在寻找的预期结果:

<book>
    <mbean code="org.book.mybooks"  name="mycompany.props.jndi:name=mybookprops">   
        <attribute name="bookprops">
            abc.mybook.onebook=@New_Value@
            def.mybook.twobook=@New_Value@
            ghi.myebook.threebook=@Value@
            ghi.myebook.fourbook=@Value@
        </attribute>
    </mbean>
</book>
4

1 回答 1

0

这有点难看,但它会做你想做的事,如果第一次没有很好地理解,我很抱歉。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:jndi="urn:jboss:jndi-binding-service:1.0"  >
    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" /> 
    <xsl:template match="book/book"> 
        <book>
            <mbean code="org.book.mybooks" name="mycompany.props.jndi:name=mybookprops">   
            <attribute name="bookprops">                 
                    <xsl:copy-of select="mbean/attribute/text()"/>
                    <xsl:call-template name="Mbean">
                        <xsl:with-param name="bindings" select="mbean/attribute"/>
                        <xsl:with-param name="bindingsP" select="/book/mbean/attribute/text()"/>
                    </xsl:call-template>     
             </attribute>           
            </mbean>
        </book>
    </xsl:template>   
    <xsl:template name="Mbean">
        <xsl:param name="bindings"/>
        <xsl:param name="bindingsP"/>          
            <xsl:choose>
                    <xsl:when test="contains($bindingsP,'@Value@')">
                          <xsl:if test="not(contains(substring-before($bindingsP,'@Value@'),'@Value@')) and not(contains(substring-before($bindingsP,'@Value@'),'@New_Value@')) and not(contains($bindings,concat(substring-before($bindingsP,'@Value@'),'@Value@')))">
                                <xsl:copy-of select="concat(substring-before($bindingsP,'@Value@'),'@Value@')"/>
                                <xsl:call-template name="Mbean">
                                   <xsl:with-param name="bindings" select="$bindings"/>
                                   <xsl:with-param name="bindingsP" select="substring-after($bindingsP,'@Value@')"/>
                                </xsl:call-template>
                            </xsl:if>                          
                    </xsl:when>
                    <xsl:when test="contains($bindingsP,'@New_Value@')">
                           <xsl:if test="not(contains(substring-before($bindingsP,'@Value@'),'@Value@')) and not(contains(substring-before($bindingsP,'@Value@'),'@New_Value@')) and not(contains($bindings,concat(substring-before($bindingsP,'@New_Value@'),'@New_Value@')))">
                                <xsl:copy-of select="concat(substring-before($bindingsP,'@New_Value@'),'@New_Value@')"/>
                                <xsl:call-template name="Mbean">
                                   <xsl:with-param name="bindings" select="$bindings"/>
                                   <xsl:with-param name="bindingsP" select="substring-after($bindingsP,'@New_Value@')"/>
                                </xsl:call-template>
                            </xsl:if>       

                    </xsl:when>
            </xsl:choose>    

    </xsl:template>

    <xsl:template match="text()"/>
</xsl:stylesheet>
于 2013-08-26T19:07:22.943 回答