XSLT 访问和创建嵌套 xml 并将标签转换为属性
Posted
技术标签:
【中文标题】XSLT 访问和创建嵌套 xml 并将标签转换为属性【英文标题】:XSLT to access and create nested xml and convert tags to attributes 【发布时间】:2022-01-02 22:02:34 【问题描述】:我有以下输入 XML 消息,需要转换为具有多个属性的嵌套 XML。
<S1>
<P>23432</P>
<Su>BG</Su>
<S2>
<P>cc</P>
<Su>B</Su>
<S3>
<P>427013947</P>
<Su>RM</Su>
<F>MDF</F>
<I>427113948</I>
<C>true</C>
<T></T>
<A>xxx</A>
</S3>
<F></F>
<I>427013947</I>
<C>true</C>
<T></T>
<A>xxxsx</A>
</S2>
<S2>
<P>cc</P>
<Su>FL</Su>
<F>1</F>
<I>427814536</I>
<C>true</C>
<T></T>
<A>xxxsx</A>
</S2>
<S2>
<P>cc</P>
<Su>G</Su>
<F></F>
<I>444</I>
<C>true</C>
<T></T>
<A>xxxsx</A>
</S2>
<F>1</F>
<I>cc</I>
<C>true</C>
<T></T>
<A>xxxs</A>
<B></B>
</S1>
输出 XML
<S1 P="23432" Su="BG" F="1" I="cc" C="true" T="" A="xxxs" B="">
<S2 P="cc" Su="B" F="" I="427013947" C="true" T="" A="xxxsx">
<S3 P="427013947" Su="RM" F="MDF" I="427113948" C="true" T="" A="xxx"></S3>
</S2>
<S2 P="cc" Su="FL" F="1" I="427814536" C="true" T="" A="xxxsx"></S2>
<S2 P="cc" Su="G" F="" I="444" C="true" T="" A="xxxsx"></S2>
</S1>
所有 S1、S2、S3 标签应保持原样,而其他子标签应作为属性添加到各自的父标签。嵌套 XML 数组的深度可达 9,如 S1、S2、S3 ...S9。
我尝试编写 XSLT 转换并尝试使用递归函数,但我无法做到。有人可以帮我写一个 XSLT 表来做这个转换吗?
我尝试了类似下面的方法(未完成),实现这一目标的最佳方法是什么?解决方案应该在 XSLT 1.0 中。
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<xsl:template match="//S1">
<xsl:element name="S1">
<xsl:for-each select="*">
<xsl:if test="local-name()!='S1'">
<xsl:attribute name="name()" >
<xsl:value-of select="text()" />
</xsl:attribute>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="S2">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:element>
</xsl:template></xsl:stylesheet>
【问题讨论】:
请发布您的最佳尝试,以便我们修复它,而不必从头开始为您编写代码。确保我们知道您的处理器支持的 XSLT 版本 【参考方案1】:如果您仅限于 XSLT 1.0,那么这会变得很尴尬,因为需要区分 Su
和 S3
。
但是,如果可以假设任何(并且唯一的)没有子元素的元素都应该转换为属性,那么这可以简单而优雅地完成:
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:apply-templates select="*[not(*)]"/>
<xsl:apply-templates select="*[*]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(*)]">
<xsl:attribute name="name()">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
【讨论】:
这只是一个示例负载。谢谢你快速的回复。它正在工作,我可以得到预期的结果。以上是关于XSLT 访问和创建嵌套 xml 并将标签转换为属性的主要内容,如果未能解决你的问题,请参考以下文章