创建 XSL 转换以展平 XML 文件,以便所有嵌套节点移动到顶级节点
Creating an XSL transformation to flatten an XML file so that all nested nodes move to the top level node
基本上我需要 XML 文件的全部内容驻留在根节点中,所以我需要更改:
<?xml version="1.0" encoding="UTF-8"?>
<sss>
<ss id="01.20211160392320">
<idenSS>
<numSS>
<list>01</list>
<seqOper>20211160392320</seqOper>
</numSS>
</idenSS>
</ss>
</sss>
像这样:
<?xml version="1.0" encoding="UTF-8"?>
<sss>
<sss_ss_idenSS_numSS_list>01</sss_ss_idenSS_numSS_list>
<sss_ss_idenSS_numSS_seqOper>20211160392320</sss_ss_idenSS_numSS_seqOper>
</sss>
我能想出的唯一方法是非常手动,而且我正在使用的 XML 非常长,所以我想以某种动态的方式构建它,而不是明确命名新标签。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:template match="/">
<sss>
<sss_ss_idenSS_numSS_list>
<xsl:value-of select="sss/ss/idenSS/numSS/list"/>
</sss_ss_idenSS_numSS_list>
<sss_ss_idenSS_numSS_seqOper>
<xsl:value-of select="sss/ss/idenSS/numSS/seqOper"/>
</sss_ss_idenSS_numSS_seqOper>
</sss>
</xsl:template>
</xsl:stylesheet>
我不太确定在你的例子中什么是不变的,什么是可以改变的。这是完全通用的东西。做得越具体,效率就越高。
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each select="//*[not(*)]">
<xsl:variable name="name">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="name()"/>
<xsl:if test="position() != last()">-</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:element name="{$name}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
基本上我需要 XML 文件的全部内容驻留在根节点中,所以我需要更改:
<?xml version="1.0" encoding="UTF-8"?>
<sss>
<ss id="01.20211160392320">
<idenSS>
<numSS>
<list>01</list>
<seqOper>20211160392320</seqOper>
</numSS>
</idenSS>
</ss>
</sss>
像这样:
<?xml version="1.0" encoding="UTF-8"?>
<sss>
<sss_ss_idenSS_numSS_list>01</sss_ss_idenSS_numSS_list>
<sss_ss_idenSS_numSS_seqOper>20211160392320</sss_ss_idenSS_numSS_seqOper>
</sss>
我能想出的唯一方法是非常手动,而且我正在使用的 XML 非常长,所以我想以某种动态的方式构建它,而不是明确命名新标签。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:template match="/">
<sss>
<sss_ss_idenSS_numSS_list>
<xsl:value-of select="sss/ss/idenSS/numSS/list"/>
</sss_ss_idenSS_numSS_list>
<sss_ss_idenSS_numSS_seqOper>
<xsl:value-of select="sss/ss/idenSS/numSS/seqOper"/>
</sss_ss_idenSS_numSS_seqOper>
</sss>
</xsl:template>
</xsl:stylesheet>
我不太确定在你的例子中什么是不变的,什么是可以改变的。这是完全通用的东西。做得越具体,效率就越高。
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each select="//*[not(*)]">
<xsl:variable name="name">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="name()"/>
<xsl:if test="position() != last()">-</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:element name="{$name}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>