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