根据属性值使用 xslt 合并两个元素 [英] merge two elements using xslt based on attribute values

查看:25
本文介绍了根据属性值使用 xslt 合并两个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的源文件的样子:

This is how my source file looks like:

<?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@ 复制所有匹配的行,并将所有其他不匹配的行复制到文件末尾.

I am looking to get merge two attributes to one and copy all the matching lines with new variable @New_Value@ and copy all other non matching lines to the end of the file.

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

This problem is pretty much similar to the question that i have posted earlier merge parent and child attributes using xslt based on attribute values only difference is the format of the content in the XML file.

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

Based on the solution that was provided in the above URL, I have tweaked my xsl to get work this new XML file, here is the xsl file:

<?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>

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

But somehow i was not able to get the expected result, following is the expected result that i am looking for:

<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>

推荐答案

虽然有点难看,但是可以满足您的需求,如果第一次没看懂,请见谅.

It's a bit ugly but it does what you want and sorry if the first time did not understand well.

<?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>

这篇关于根据属性值使用 xslt 合并两个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆