2013-03-01 74 views
0

由於WPF中的GroupBox控件只接受一個WPF控件作爲內容,所以我必須首先將所有屬性包裝到DockPanel控件中。XSL轉換| XML到XAML |添加層次結構級別以嵌套元素

我用下面的XSL樣式錶轉換我的代碼到後來顯示的XAML代碼段 樣式表(片斷):

<!-- Default attribute processing --> 
    <xsl:template name="process-element"> 
    <xsl:param name="attr" /> 

    <!-- Process all attributes and elements which are going to be 
      transformed to attributes --> 
    <xsl:apply-templates select="@*|*" mode="to-attr" /> 
    <!-- Add extra attribute --> 
    <xsl:if test="$attr"> 
     <xsl:attribute name="{substring-after($attr, '|')}"> 
     <xsl:value-of select="@*[local-name() = substring-before($attr, '|')]" /> 
     </xsl:attribute> 
    </xsl:if> 
    <!-- Process children elements --> 
    <xsl:apply-templates select="*" /> 
    </xsl:template> 

    <!-- Map GroupBoxWrapper into GroupBox --> 
    <xsl:template match="GroupBoxWrapper"> 
    <xsl:element name="GroupBox"> 
     <!-- TODO: Add DockPanel Element and move "cursor" one level upwards --> 
     <!--<xsl:element name="DockPanel">--> 
     <xsl:call-template name="process-element"> 
      <xsl:with-param name="attr"/> 
     </xsl:call-template> 
     <!--</xsl:element>--> 
    </xsl:element> 
    </xsl:template> 

這是生成的代碼XAML:

<GroupBox Name="groupbox1" DockPanel.Dock="Left, Right, Top, Bottom" Width="1092" Height="125" Background="Transparent" Foreground="#0046D5" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="False"> 
    <DockPanel Name="panel4" DockPanel.Dock="Top" Width="1078" Height="25" Background="Transparent" Visibility="visible"> 
    <Label Name="lblName" DockPanel.Dock="Left" Width="100" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="False" Content="Name:" /> 
    <TextBox Name="txtName" DockPanel.Dock="Left" Width="100" Height="25" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Text="" /> 
    </DockPanel> 
    <DockPanel Name="panel5" DockPanel.Dock="Top" Width="1078" Height="25" Background="Transparent" Visibility="visible"> 
    <Label Name="lblLastName" DockPanel.Dock="Left" Width="100" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="False" Content="Lastname:" /> 
    <TextBox Name="txtLastName" DockPanel.Dock="Left" Width="100" Height="25" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Text="" /> 
    </DockPanel> 
    <DockPanel Name="panel6" DockPanel.Dock="Top" Width="1078" Height="25" Background="Transparent" Visibility="visible"> 
    <Label Name="label4" DockPanel.Dock="Left" Width="100" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="False" Content="Age:" /> 
    <TextBox Name="textbox3" DockPanel.Dock="Left" Width="100" Height="25" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Text="" /> 
    </DockPanel> 
    <DockPanel Name="panel14" DockPanel.Dock="Top" Width="1078" Height="25" Background="Transparent" Visibility="visible"> 
    <Label Name="label9" DockPanel.Dock="Left" Width="100" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="False" Content="Gender:" /> 
    <RadioButton Name="radiobutton1" DockPanel.Dock="Left" Width="75" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Content="Male" /> 
    <RadioButton Name="radiobutton2" DockPanel.Dock="Left" Width="75" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="2" IsTabStop="True" Content="Female" /> 
    </DockPanel> 
</GroupBox> 

問題在於GroupBox現在包含四個WPF中不可能的元素。這就是爲什麼我需要將這些控件包裝到一個DockPanel中。

當我取消註釋<xsl:element name="DockPanel">線XAML代碼看起來是這樣的:

<GroupBox> <!-- attributes should appear on this line --> 
     <DockPanel Name="groupbox1" DockPanel.Dock="Left, Right, Top, Bottom" Width="1092" Height="125" Background="Transparent" Foreground="#0046D5" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="False"> 
     <DockPanel Name="panel4" DockPanel.Dock="Top" Width="1078" Height="25" Background="Transparent" Visibility="visible"> 
      <Label Name="lblName" DockPanel.Dock="Left" Width="100" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="False" Content="Name:" /> 
      <TextBox Name="txtName" DockPanel.Dock="Left" Width="100" Height="25" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Text="" /> 
     </DockPanel> 
     <DockPanel Name="panel5" DockPanel.Dock="Top" Width="1078" Height="25" Background="Transparent" Visibility="visible"> 
      <Label Name="lblLastName" DockPanel.Dock="Left" Width="100" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="False" Content="Lastname:" /> 
      <TextBox Name="txtLastName" DockPanel.Dock="Left" Width="100" Height="25" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Text="" /> 
     </DockPanel> 
     <DockPanel Name="panel6" DockPanel.Dock="Top" Width="1078" Height="25" Background="Transparent" Visibility="visible"> 
      <Label Name="label4" DockPanel.Dock="Left" Width="100" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="False" Content="Age:" /> 
      <TextBox Name="textbox3" DockPanel.Dock="Left" Width="100" Height="25" Background="Azure" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Text="" /> 
     </DockPanel> 
     <DockPanel Name="panel14" DockPanel.Dock="Top" Width="1078" Height="25" Background="Transparent" Visibility="visible"> 
      <Label Name="label9" DockPanel.Dock="Left" Width="100" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="0" IsTabStop="False" Content="Gender:" /> 
      <RadioButton Name="radiobutton1" DockPanel.Dock="Left" Width="75" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="1" IsTabStop="True" Content="Male" /> 
      <RadioButton Name="radiobutton2" DockPanel.Dock="Left" Width="75" Height="25" Background="Transparent" Foreground="Black" Visibility="visible" BorderThickness="1,1,1,1" FontFamily="Tahoma" FontSize="9" TabIndex="2" IsTabStop="True" Content="Female" /> 
     </DockPanel> 
     </DockPanel> 
    </GroupBox> 

全部屬性,其意圖在那裏對分組框中是其中嵌套的內分組框中元件DockPanel中元件。

我需要弄清楚如何創建DockPanel元素(檢查)並向上移動到GroupBox元素來調用過程元素模板。

任何想法?

+0

你的輸入XML是什麼樣的?你想要的輸出是什麼樣的?模式爲'to-attr'的模板是什麼樣的?您不能首先創建DockPanel元素,然後移出它以添加屬性,因此您需要一種替代方法,這需要您提供更多信息。 – JLRishe 2013-03-01 14:08:07

+0

雖然只是一個建議,但您可以使用XML-to-XAML,但在基於XAML的技術中,有一個名爲'ItemsControl'的東西,它應該替換所有重複標籤+文本框的東西,給定一個適當的'DataTemplate'和要綁定的數據項。如果你這樣做,我認爲你的XSLT生成的XAML不會像應該那樣可維護。 – 2013-03-01 14:37:50

+0

@JLRishe「您不能先創建DockPanel元素,然後移出它以添加屬性」。他試圖實現的是將某些子元素(可以出現在任何位置)轉換爲父元素中的屬性。如果他在處理所有內容的同時處理這些目標元素之前的某些元素,並且在添加子元素之後XSLT不允許添加屬性。因此,其中一種選擇是使用「to-attr」模式處理所有這些元素,以便可以先處理它們,然後恢復「正常」處理。所以這只是一種排序... – 2013-03-01 15:19:54

回答

0

問題

工藝元件模板的目的是做到以下幾點:

  1. 變換的當前屬性和當前元素的子元素作爲新元素的屬性。
  2. 使用attr參數添加額外屬性
  3. 正常處理子項。

是當前已出現是因爲要附加在步驟1中的屬性問題(< XSL:申請模板選擇=「@|」模式=「到ATTR」>)到新創建的元素DockPanel(< xsl:element name =「DockPanel」>)。這就是爲什麼你的屬性被複制到其他元素中的原因。

SOLUTION

不要依賴模板的過程元素做這種轉變。最初,當某個點(XML to XAML transformation using XSLT 1.0 | Exclude specific transformations for some controls)的所有元素都遵循不同的邏輯來保存重複代碼時,就會編寫該模板。因此,如果您嘗試實現的內容不符合之前的模式,則必須修改流程模板或爲GroupBoxWrapper元素編寫不同的模板。

以下模板將修復您嘗試實現的內容。

<!-- Map GroupBoxWrapper into GroupBox --> 
    <xsl:template match="GroupBoxWrapper"> 
    <xsl:element name="GroupBox"> 
     <!-- Process attributes --> 
     <xsl:apply-templates select="@*|*" mode="to-attr" /> 
     <!-- Create new DockPanel to wrap children --> 
     <xsl:element name="DockPanel"> 
     <!-- Process GroupBoxWrapper chldren --> 
     <xsl:apply-templates select="*" /> 
     </xsl:element> 
    </xsl:element> 
    </xsl:template> 

PS。我認爲你應該首先理解我們[在stackoverflow上的人]發佈的代碼,然後才能真正使用它,所以每次出現問題時都不必依賴於我們。