Expand XML depth with XSLT transformation

问题描述:

I'm trying to convert an xml that has a root element and one level deep of child elements. These elements can have the same attribute name. What I am looking for is a way to transform the xml in such a way that the related attributes are nested correctly.

The xml is generated by an HTML form submission (I have control over the form field names).

The resulting XML is generated:

Input.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>

Desired output

<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>

My Attempt

Note: I prepended 'r_' to the repeated attributes. <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>

Output.xml

<root>

<project>

<id></id>

<name></name>

</project>

<project>

<id></id>

<name></name>

<id></id>

<name></name>

</project>

</root>

Is there a simpler method to creating unique XML elements without having to create a extremely verbose xslt transformation that captures all possible repeated elements?

网友答案:

I can't follow the logic of your XSLT. Is there a reason why this couldn't be simply: