使用 XSLT xsl:for-each 在 XML 中插入元素
Insert element in XML using XSLT xsl:for-each
我想在 xml 中间插入一些元素并在 XML 中删除一些元素。
请在下面找到用于转换 xml 的 XSLT。
<xsl:template match="/">
<xsl:element name="CLASSES">
<xsl:copy-of select="INPUT/POST/CLASSES/CLASS" />
<xsl:variable name="previous_id">
<xsl:value-of select="INPUT/PRE/CLASSES/STUDENTS/STUDENTADD/ID"></xsl:value-of>
</xsl:variable>
<xsl:element name="STUDENTS">
<xsl:for-each select="INPUT/POST/CLASSES/STUDENTS/STUDENTADD">
<xsl:choose>
<xsl:when test="$previous_id = ID">
<xsl:element name="change_code">
<xsl:value-of select="123" />
</xsl:element>
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:for-each select="INPUT/PRE/CLASSES/STUDENTS/STUDENTADD">
<xsl:element name="change_code">
<xsl:value-of select="124" />
</xsl:element>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:template>
我得到如下带有插入元素的输出。
<CLASSES>
<CLASS>
<CLASSNAME>SIXTH</CLASSNAME>
<NOOFSTUDENT>60</NOOFSTUDENT>
</CLASS>
<STUDENTS>
<change_code>123</change_code>
<STUDENTADD>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>123456</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>29-12-2015</STARTDATE>
</STUDENTADD>
<STUDENTADD>
<ID>2</ID>
<ADDRESS>
<POST_TOWN>W4589652</POST_TOWN>
<POST_CODE>51896</POST_CODE>
</ADDRESS>
<STARTDATE>25-12-2016</STARTDATE>
<END_DATE>25-12-2016</END_DATE>
</STUDENTADD>
<change_code>124</change_code>
<STUDENTADD>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>12345692</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>2015-12-29</STARTDATE>
</STUDENTADD>
</STUDENTS>
</CLASSES>
我想要的是 change_code 元素应该在 STUdENT_ADD 聚合中。
我应该如何更改 xslt?
下面输入XML。
<INPUT>
<POST>
<CLASSES>
<CLASS>
<CLASSNAME>SIXTH</CLASSNAME>
<NOOFSTUDENT>60</NOOFSTUDENT>
</CLASS>
<STUDENTS>
<STUDENTADD>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>123456</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>29-12-2015</STARTDATE>
</STUDENTADD>
<STUDENTADD>
<ID>2</ID>
<ADDRESS>
<POST_TOWN>W4589652</POST_TOWN>
<POST_CODE>51896</POST_CODE>
</ADDRESS>
<STARTDATE>25-12-2016</STARTDATE>
<END_DATE>25-12-2016</END_DATE>
</STUDENTADD>
</STUDENTS>
</CLASSES>
</POST>
<PRE>
<CLASSES>
<STUDENTS>
<STUDENTADD>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>12345692</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>2015-12-29</STARTDATE>
</STUDENTADD>
</STUDENTS>
</CLASSES>
</PRE>
</INPUT>
与使用 <xsl:for-each>
相比,使用模板可以简化 XSLT。由于输出中保留了很多节点,可以使用identity template
开头。
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
然后所有<STUDENTADD>
节点都将包含在<STUDENTS>
下,这可以通过
完成
<xsl:template match="INPUT">
<CLASSES>
<xsl:apply-templates select="POST/CLASSES/CLASS" />
<STUDENTS>
<xsl:apply-templates select="POST/CLASSES/STUDENTS/STUDENTADD" />
<xsl:apply-templates select="PRE/CLASSES/STUDENTS/STUDENTADD" />
</STUDENTS>
</CLASSES>
</xsl:template>
最后,将添加一个新节点 <CHANGE_CODE>
作为 <STUDENTADD>
的子节点。这里的假设是,如果 <STUDENTADD>
的祖先恰好是 <POST>
那么 <CHANGE_CODE>
的值将是 123
如果它是 <PRE>
那么值将是 124
.
<xsl:template match="STUDENTADD">
<xsl:copy>
<xsl:choose>
<xsl:when test="ancestor::POST">
<CHANGE_CODE>123</CHANGE_CODE>
</xsl:when>
<xsl:when test="ancestor::PRE">
<CHANGE_CODE>124</CHANGE_CODE>
</xsl:when>
</xsl:choose>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
下面是完整的 XSLT 和输出。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:strip-space elements="*" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="INPUT">
<CLASSES>
<xsl:apply-templates select="POST/CLASSES/CLASS" />
<STUDENTS>
<xsl:apply-templates select="POST/CLASSES/STUDENTS/STUDENTADD" />
<xsl:apply-templates select="PRE/CLASSES/STUDENTS/STUDENTADD" />
</STUDENTS>
</CLASSES>
</xsl:template>
<xsl:template match="STUDENTADD">
<xsl:copy>
<xsl:choose>
<xsl:when test="ancestor::POST">
<CHANGE_CODE>123</CHANGE_CODE>
</xsl:when>
<xsl:when test="ancestor::PRE">
<CHANGE_CODE>124</CHANGE_CODE>
</xsl:when>
</xsl:choose>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出
<CLASSES>
<CLASS>
<CLASSNAME>SIXTH</CLASSNAME>
<NOOFSTUDENT>60</NOOFSTUDENT>
</CLASS>
<STUDENTS>
<STUDENTADD>
<CHANGE_CODE>123</CHANGE_CODE>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>123456</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>29-12-2015</STARTDATE>
</STUDENTADD>
<STUDENTADD>
<CHANGE_CODE>123</CHANGE_CODE>
<ID>2</ID>
<ADDRESS>
<POST_TOWN>W4589652</POST_TOWN>
<POST_CODE>51896</POST_CODE>
</ADDRESS>
<STARTDATE>25-12-2016</STARTDATE>
<END_DATE>25-12-2016</END_DATE>
</STUDENTADD>
<STUDENTADD>
<CHANGE_CODE>124</CHANGE_CODE>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>12345692</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>2015-12-29</STARTDATE>
</STUDENTADD>
</STUDENTS>
</CLASSES>
我想在 xml 中间插入一些元素并在 XML 中删除一些元素。
请在下面找到用于转换 xml 的 XSLT。
<xsl:template match="/">
<xsl:element name="CLASSES">
<xsl:copy-of select="INPUT/POST/CLASSES/CLASS" />
<xsl:variable name="previous_id">
<xsl:value-of select="INPUT/PRE/CLASSES/STUDENTS/STUDENTADD/ID"></xsl:value-of>
</xsl:variable>
<xsl:element name="STUDENTS">
<xsl:for-each select="INPUT/POST/CLASSES/STUDENTS/STUDENTADD">
<xsl:choose>
<xsl:when test="$previous_id = ID">
<xsl:element name="change_code">
<xsl:value-of select="123" />
</xsl:element>
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:for-each select="INPUT/PRE/CLASSES/STUDENTS/STUDENTADD">
<xsl:element name="change_code">
<xsl:value-of select="124" />
</xsl:element>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:template>
我得到如下带有插入元素的输出。
<CLASSES>
<CLASS>
<CLASSNAME>SIXTH</CLASSNAME>
<NOOFSTUDENT>60</NOOFSTUDENT>
</CLASS>
<STUDENTS>
<change_code>123</change_code>
<STUDENTADD>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>123456</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>29-12-2015</STARTDATE>
</STUDENTADD>
<STUDENTADD>
<ID>2</ID>
<ADDRESS>
<POST_TOWN>W4589652</POST_TOWN>
<POST_CODE>51896</POST_CODE>
</ADDRESS>
<STARTDATE>25-12-2016</STARTDATE>
<END_DATE>25-12-2016</END_DATE>
</STUDENTADD>
<change_code>124</change_code>
<STUDENTADD>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>12345692</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>2015-12-29</STARTDATE>
</STUDENTADD>
</STUDENTS>
</CLASSES>
我想要的是 change_code 元素应该在 STUdENT_ADD 聚合中。
我应该如何更改 xslt?
下面输入XML。
<INPUT>
<POST>
<CLASSES>
<CLASS>
<CLASSNAME>SIXTH</CLASSNAME>
<NOOFSTUDENT>60</NOOFSTUDENT>
</CLASS>
<STUDENTS>
<STUDENTADD>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>123456</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>29-12-2015</STARTDATE>
</STUDENTADD>
<STUDENTADD>
<ID>2</ID>
<ADDRESS>
<POST_TOWN>W4589652</POST_TOWN>
<POST_CODE>51896</POST_CODE>
</ADDRESS>
<STARTDATE>25-12-2016</STARTDATE>
<END_DATE>25-12-2016</END_DATE>
</STUDENTADD>
</STUDENTS>
</CLASSES>
</POST>
<PRE>
<CLASSES>
<STUDENTS>
<STUDENTADD>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>12345692</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>2015-12-29</STARTDATE>
</STUDENTADD>
</STUDENTS>
</CLASSES>
</PRE>
</INPUT>
与使用 <xsl:for-each>
相比,使用模板可以简化 XSLT。由于输出中保留了很多节点,可以使用identity template
开头。
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
然后所有<STUDENTADD>
节点都将包含在<STUDENTS>
下,这可以通过
<xsl:template match="INPUT">
<CLASSES>
<xsl:apply-templates select="POST/CLASSES/CLASS" />
<STUDENTS>
<xsl:apply-templates select="POST/CLASSES/STUDENTS/STUDENTADD" />
<xsl:apply-templates select="PRE/CLASSES/STUDENTS/STUDENTADD" />
</STUDENTS>
</CLASSES>
</xsl:template>
最后,将添加一个新节点 <CHANGE_CODE>
作为 <STUDENTADD>
的子节点。这里的假设是,如果 <STUDENTADD>
的祖先恰好是 <POST>
那么 <CHANGE_CODE>
的值将是 123
如果它是 <PRE>
那么值将是 124
.
<xsl:template match="STUDENTADD">
<xsl:copy>
<xsl:choose>
<xsl:when test="ancestor::POST">
<CHANGE_CODE>123</CHANGE_CODE>
</xsl:when>
<xsl:when test="ancestor::PRE">
<CHANGE_CODE>124</CHANGE_CODE>
</xsl:when>
</xsl:choose>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
下面是完整的 XSLT 和输出。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:strip-space elements="*" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="INPUT">
<CLASSES>
<xsl:apply-templates select="POST/CLASSES/CLASS" />
<STUDENTS>
<xsl:apply-templates select="POST/CLASSES/STUDENTS/STUDENTADD" />
<xsl:apply-templates select="PRE/CLASSES/STUDENTS/STUDENTADD" />
</STUDENTS>
</CLASSES>
</xsl:template>
<xsl:template match="STUDENTADD">
<xsl:copy>
<xsl:choose>
<xsl:when test="ancestor::POST">
<CHANGE_CODE>123</CHANGE_CODE>
</xsl:when>
<xsl:when test="ancestor::PRE">
<CHANGE_CODE>124</CHANGE_CODE>
</xsl:when>
</xsl:choose>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出
<CLASSES>
<CLASS>
<CLASSNAME>SIXTH</CLASSNAME>
<NOOFSTUDENT>60</NOOFSTUDENT>
</CLASS>
<STUDENTS>
<STUDENTADD>
<CHANGE_CODE>123</CHANGE_CODE>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>123456</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>29-12-2015</STARTDATE>
</STUDENTADD>
<STUDENTADD>
<CHANGE_CODE>123</CHANGE_CODE>
<ID>2</ID>
<ADDRESS>
<POST_TOWN>W4589652</POST_TOWN>
<POST_CODE>51896</POST_CODE>
</ADDRESS>
<STARTDATE>25-12-2016</STARTDATE>
<END_DATE>25-12-2016</END_DATE>
</STUDENTADD>
<STUDENTADD>
<CHANGE_CODE>124</CHANGE_CODE>
<ID>1</ID>
<ADDRESS>
<POST_TOWN>12345692</POST_TOWN>
<POST_CODE>56859542</POST_CODE>
</ADDRESS>
<STARTDATE>2015-12-29</STARTDATE>
</STUDENTADD>
</STUDENTS>
</CLASSES>