Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XSLT将同级节点字段添加到父节点_Xslt_Xslt 1.0 - Fatal编程技术网

使用XSLT将同级节点字段添加到父节点

使用XSLT将同级节点字段添加到父节点,xslt,xslt-1.0,Xslt,Xslt 1.0,我的要求是将同级E_记录字段移动到L_记录中。你能检查一下我在哪里遗漏了逻辑吗。XSLT代码将所有E_记录字段推送到每个L_记录中。请检查第二根第二个L_记录 我正在使用以下输入XML <Record> <H_Record> <Rec_Type>H</Rec_Type> </H_Record> <C_Record> <Rec_Type>C</

我的要求是将同级E_记录字段移动到L_记录中。你能检查一下我在哪里遗漏了逻辑吗。XSLT代码将所有E_记录字段推送到每个L_记录中。请检查第二根第二个L_记录

我正在使用以下输入XML

  <Record>
     <H_Record>
        <Rec_Type>H</Rec_Type>
     </H_Record>
     <C_Record>
        <Rec_Type>C</Rec_Type>
     </C_Record>
     <L_Record>
        <Rec_Type>L</Rec_Type>
        <L_Level>2</L_Level>
     </L_Record>
     <E_Record>
        <Rec_Type>E</Rec_Type>
        <E_Qty>3</E_Qty>
     </E_Record>
     <E_Record>
        <Rec_Type>E</Rec_Type>
        <E_Qty>4</E_Qty>
     </E_Record>
     <L_Record>
        <Rec_Type>L</Rec_Type>
        <L_Level>2</L_Level>
     </L_Record>
     <R_Record>
        <Rec_Type>R</Rec_Type>
     </R_Record>
  </Record>
  <Record>
     <H_Record>
        <Rec_Type>H</Rec_Type>
     </H_Record>
     <C_Record>
        <Rec_Type>C</Rec_Type>
     </C_Record>
     <L_Record>
        <Rec_Type>L</Rec_Type>
        <L_Level>2</L_Level>
     </L_Record>
     <L_Record>
        <Rec_Type>L</Rec_Type>
        <L_Level>2</L_Level>
     </L_Record>
     <E_Record>
        <Rec_Type>E</Rec_Type>
        <E_Qty>1</E_Qty>
     </E_Record>
     <E_Record>
        <Rec_Type>E</Rec_Type>
        <E_Qty>2</E_Qty>
     </E_Record>
     <L_Record>
        <Rec_Type>L</Rec_Type>
        <L_Level>2</L_Level>
     </L_Record>
     <E_Record>
        <Rec_Type>E</Rec_Type>
        <E_Qty>5</E_Qty>
     </E_Record>
     <E_Record>
        <Rec_Type>E</Rec_Type>
        <E_Qty>6</E_Qty>
     </E_Record>
     <R_Record>
        <Rec_Type>R</Rec_Type>
     </R_Record>
  </Record>
  </root>

您可以使用此解决方案:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">

    <xsl:output method="xml" indent="yes"/>

    <!-- Replace first E_Record in a Record -->
    <xsl:template match="E_Record[position()=1]">
        <L_Record>
            <Rec_Type>L</Rec_Type>
            <L_Level>2</L_Level>
            <!-- Copy all contents of E_Record siblings -->
            <xsl:copy-of select="../E_Record/*"/>
        </L_Record>
    </xsl:template>

    <!-- Eliminate all other E_Record -->
    <xsl:template match="E_Record"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

L
2.
看到它在这里工作:

更新版本:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">


    <xsl:output method="xml" indent="yes"/>

    <!-- Replace E_Record immediately following an L_Record -->
    <xsl:template match="E_Record[name(preceding-sibling::*[1])='L_Record']">
        <L_Record>
            <Rec_Type>L</Rec_Type>
            <L_Level>2</L_Level>
            <!-- Copy the contents of the current E_Record -->
            <xsl:copy-of select="*"/>
            <!-- Call template to copy next E_Record -->
            <xsl:call-template name="copyNextE">
                <xsl:with-param name="next" select="following-sibling::*[1]"/>
            </xsl:call-template>
        </L_Record>
    </xsl:template>

    <!-- Recursive template, will call itself until the next sibling is not an E_Record -->
    <xsl:template name="copyNextE">
        <xsl:param name="next"/>
        <!-- If we are still dealing with an E_Record -->
        <xsl:if test="name($next)='E_Record'">
            <xsl:copy-of select="$next/*"/>
            <xsl:call-template name="copyNextE">
                <!-- Call the same template with the next sibling -->
                <xsl:with-param name="next" select="$next/following-sibling::*[1]"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <!-- Eliminate all other E_Record -->
    <xsl:template match="E_Record"/>

    <!-- Identity template -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

L
2.

看到它在这里工作了吗:

嗨,塞巴斯蒂安,看起来你的代码执行的输出与我的相同。为了澄清这一点,同级E_记录字段只应追加到前面的L_记录中。但并非所有的E_记录字段。请检查输出XML记录[2]/L_记录[2]/E_记录。它将所有E_记录字段捕获到第二个L_记录中。@SrinivasBajina好的,我知道你想做什么了。第一条记录很简单,但第二条不同。我不知道该怎么做。您需要进行某种分组,这在xslt-2.0中会更容易。感谢您的投入,我们正在尝试使用xslt 1.0实现这一点,因为我的应用程序还没有为XSLT2.0Hi专家做好准备,有人可以帮助我吗?我在某个地方遗漏了逻辑,我不知道它到底在哪里。@SrinivasBajina我已经更新了我的答案。我认为它现在产生了您所期望的输出。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="L_Record">
        <xsl:copy>
            <xsl:apply-templates/>
            <xsl:if test="following-sibling::*[1][self::E_Record]">
            <xsl:call-template name="Next_E_Record">
                <xsl:with-param name="next" select="following-sibling::*[self::E_Record]/*"></xsl:with-param>
            </xsl:call-template>
            </xsl:if>
        </xsl:copy>
    </xsl:template>

   <xsl:template name="Next_E_Record">
       <xsl:param name="next"/>
       <xsl:copy-of select="$next"/>
       <xsl:if test="$next/following-sibling::*[1][self::E_Record]">
           <xsl:call-template name="Next_E_Record">
               <xsl:with-param name="next" select="$next/following-sibling::*[self::E_Record]/*"></xsl:with-param>
           </xsl:call-template>
       </xsl:if>
   </xsl:template>

    <xsl:template match="E_Record"/>

</xsl:stylesheet>
enter code here
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">

    <xsl:output method="xml" indent="yes"/>

    <!-- Replace first E_Record in a Record -->
    <xsl:template match="E_Record[position()=1]">
        <L_Record>
            <Rec_Type>L</Rec_Type>
            <L_Level>2</L_Level>
            <!-- Copy all contents of E_Record siblings -->
            <xsl:copy-of select="../E_Record/*"/>
        </L_Record>
    </xsl:template>

    <!-- Eliminate all other E_Record -->
    <xsl:template match="E_Record"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">


    <xsl:output method="xml" indent="yes"/>

    <!-- Replace E_Record immediately following an L_Record -->
    <xsl:template match="E_Record[name(preceding-sibling::*[1])='L_Record']">
        <L_Record>
            <Rec_Type>L</Rec_Type>
            <L_Level>2</L_Level>
            <!-- Copy the contents of the current E_Record -->
            <xsl:copy-of select="*"/>
            <!-- Call template to copy next E_Record -->
            <xsl:call-template name="copyNextE">
                <xsl:with-param name="next" select="following-sibling::*[1]"/>
            </xsl:call-template>
        </L_Record>
    </xsl:template>

    <!-- Recursive template, will call itself until the next sibling is not an E_Record -->
    <xsl:template name="copyNextE">
        <xsl:param name="next"/>
        <!-- If we are still dealing with an E_Record -->
        <xsl:if test="name($next)='E_Record'">
            <xsl:copy-of select="$next/*"/>
            <xsl:call-template name="copyNextE">
                <!-- Call the same template with the next sibling -->
                <xsl:with-param name="next" select="$next/following-sibling::*[1]"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <!-- Eliminate all other E_Record -->
    <xsl:template match="E_Record"/>

    <!-- Identity template -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>