2012-06-25 35 views
0

儘管我已經看過並閱讀了很多關於如何將屬性轉換爲元素的帖子,沒有任何示例做我需要的東西。 我有一個平整的xml並將其轉換爲一個完整的樹面向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

下面是一個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> 

不像大多數我的答案,這是完整的和測試,給出了至少您所提供的示例文件,你需要的輸出。

+0

感謝您的解決方案,雖然我無法在緊湊的框架上使用xslt2。 此外,xsl並不會完全產生所需的輸出。 – josef

+0

感謝您的解決方案,雖然我無法在緊湊框架上使用xslt2。 此外,xsl並不會完全產生所需的輸出。 有一個沒有屬性的組標籤,而不是組名=「ITCHealth」之一。 – josef