我正在尝试转换一个具有根元素和一层子元素的xml。这些元素可以具有相同的属性名称。我正在寻找的是一种以相关属性正确嵌套的方式转换xml的方法。
xml是由HTML表单提交生成的(我可以控制表单字段名称)。
生成生成的XML:
<root>
<project_id>1</project_id>
<project_name>Project 1</project_name>
<project_id>2</project_id>
<project_name>Project 2</project_name>
<project_id>3</project_id>
<project_name>Project 3</project_name>
</root>
<root>
<project>
<id>1</id>
<name>Project 1</name>
</project>
<project>
<id>2</id>
<name>Project 2</name>
</project>
<project>
<id>3</id>
<name>Project 3</name>
</project>
<root>
注意:我将'r_'添加到重复的属性中。 <r_project_id> 2</r_project_id>
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="node()|@*">
<project>
<xsl:apply-templates select="*[matches(name(), '^project_')]"/>
</project>
<project>
<xsl:apply-templates select="*[matches(name(), '^r_project')]"/>
</project>
</xsl:template>
<xsl:template match="*[matches(name(), '^r_project_')]">
<xsl:apply-templates select="*[matches(name(), '^r_project_')]"/>
<xsl:copy-of select="*"/>
</xsl:template>
<xsl:template match="*[matches(name(), '^project_')]">
<xsl:element name="{replace(name(), '^project_', '')}">
<xsl:copy-of select="*"/>
</xsl:element>
</xsl:template>
<xsl:template match="*[matches(name(), '^r_project_')]">
<xsl:element name="{replace(name(), '^r_project_', '')}">
<xsl:copy-of select="*"/>
</xsl:element>
</xsl:template>
<root>
<project>
<id></id>
<name></name>
</project>
<project>
<id></id>
<name></name>
<id></id>
<name></name>
</project>
</root>
是否有一种更简单的方法来创建唯一的XML元素,而无需创建捕获所有可能重复元素的极其冗长的xslt转换?
答案 0 :(得分:2)
来自michael.hor257k的解决方案看起来不错,但XSLT 2.0中的一个更惯用且更灵活的解决方案可能
<xsl:template match="/">
<root>
<xsl:for-each-group select="root/*" group-starting-with="project_id">
<project>
<xsl:apply-templates select="current-group()" mode="rename"/>
</project>
</xsl:for-each>
</root>
</xsl:template>
<xsl:template match="*" mode="rename">
<xsl:element name="{substring-after(name(), 'project_')}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
答案 1 :(得分:1)
我无法遵循XSLT的逻辑。有什么理由不能简单地说:
<xsl:template match="/">
<root>
<xsl:for-each select="root/project_id">
<project>
<id><xsl:value-of select="."/></id>
<name><xsl:value-of select="following-sibling::project_name"/></name>
</project>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>