虽然我已经看过很多关于如何将属性转换为元素的帖子,但没有一个例子可以满足我的需要。 我有一个扁平的xml,并将其转换为完整的树导向xml:
输入:
<Subsystem Name="Device Monitor">
<Group Name="ITCHealth">
<Field Name="System\AttachedDevice\OneWire\Count" Type="Integer">0</Field>
<Field Name="System\AttachedDevice\OneWire\Asset" Type="String">Str</Field>
<Field Name="System\AttachedDevice\USB\Count" Type="Integer">0</Field>
<Field Name="System\AttachedDevice\USB\Name" Type="Integer">0</Field>
<Field Name="System\Camera\Enabled" Type="Boolean">true</Field>
<Field Name="System\Camera\Present" Type="Boolean">true</Field>
<Field Name="Network\BlueTooth\RadioStatus" Type="String">Str</Field>
</Group>
</Subsystem>
期望的输出:
<Subsystem Name="Device Monitor">
<Group Name="ITCHealth">
<Group Name="System">
<Group Name="AttachedDevice">
<Group Name="OneWire">
<Field Name="Count" Type="Integer">0</Field>
<Field Name="Asset" Type="String">Str</Field>
</Group>
<Group Name="USB ">
<Field Name="Count" Type="Integer">0</Field>
<Field Name="Name" Type="Integer">0</Field>
</Group>
</Group>
<Group Name="Camera">
<Field Name="Enabled" Type="Boolean">true</Field>
<Field Name="Present" Type="Boolean">true</Field>
</Group>
</Group>
<Group Name="Network">
<Group Name="Bluetooth">
<Field Name="Radiostatus" Type="String">Str</Field>
</Group>
</Group>
</Group>
</Subsystem>
我更喜欢CSharp解决方案。
感谢您的帮助
答案 0 :(得分:0)
这是一个XSLT 2.0解决方案(有几个XSLT 2.0处理器可以从C#轻松调用)。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="Group">
<xsl:copy>
<xsl:call-template name="group-fields">
<xsl:with-param name="fields" select="Field"/>
<xsl:with-param name="depth" select="1"/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="group-fields">
<xsl:param name="fields" as="element(Field)*"/>
<xsl:param name="depth"/>
<xsl:for-each-group select="$fields" group-by="tokenize(@Name, '\\')[$depth]">
<xsl:choose>
<xsl:when test="count(current-group()) = 1 and count(tokenize(@Name, '\\')) = $depth">
<Field Name="{current-grouping-key()}" Type="{@Type}">
<xsl:value-of select="."/>
</Field>
</xsl:when>
<xsl:otherwise>
<Group Name="{current-grouping-key()}">
<xsl:call-template name="group-fields">
<xsl:with-param name="fields" select="current-group()"/>
<xsl:with-param name="depth" select="$depth + 1"/>
</xsl:call-template>
</Group>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
与我的大部分答案不同,这是完整的并经过测试,以提供您所需的输出,至少在您提供的示例文档中。