[英]Transform XML to XAML with XSL
可以说我在xml中有以下代码片段:
<PanelWrapper id="RootPanel"
dock="Fill"
width="1092"
height="605"
backcolor="Transparent"
visible="True">
<ButtonWrapper id="button1"
dock="Left"
text="TestButton"
width="75"
height="605"
border-left="1"
border-top="1"
border-right="1"
border-bottom="1"
font-name="Tahoma"
font-size="9"
font-style="Regular">
</ButtonWrapper>
</PanelWrapper>
我需要将xml代码转换为XAML。 预期的最终结果应如下所示:
<WrapPanel Name="RootPanel"
DockPanel.Dock="Left, Right, Top, Bottom"
Width="1092" Height="605"
Background="Transparent"
Visibility="Visible">
<Button Name="button1"
DockPanel.Dock ="Left"
Content="TestButton"
Width="75"
Height="605"
BorderThickness="1,1,1,1"
FontFamily="Tahoma"
FontSize="9"
FontStyle="Normal">
</Button>
</WrapPanel>
xsl样式表可以进行这种转换吗?
我特别在问这样的转换:
从
border-left="1"
border-top="1"
border-right="1"
border-bottom="1"
至
BorderThickness="1,1,1,1"
或来自
visible="True"
至
Visibility="Visible"
可以完成此转换。 我假设您使用的是XSLT 1.0,那么XSLT 2.0中的解决方案会更短(因为要实现2,我必须要做递归模板)。 我还假设:
代码的思想是手动匹配每个属性,并将其值替换为正确的值。 因为我不知道遵循所有属性的逻辑(除了我在1.和2中假定的位),所以转换仅限于给定的XML,但是我希望它能为您提供实现目标的思路试图做。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<!-- Ignore attributes by default, so we can have more control
about unhandled attributes -->
<xsl:template match="@*" />
<!-- Transform PanelWrapper to WrapPannel -->
<xsl:template match="PanelWrapper">
<WrapPanel>
<xsl:apply-templates select="@*|*" />
</WrapPanel>
</xsl:template>
<!-- Transform ButtonWrapper to Button -->
<xsl:template match="ButtonWrapper">
<Button>
<xsl:apply-templates select="@*" />
</Button>
</xsl:template>
<!-- Map id attribute to Name -->
<xsl:template match="@id">
<xsl:attribute name="Name">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<!-- Map @dock = 'Fill' to @dock = 'Left, Right...etc' -->
<xsl:template match="@dock[. = 'Fill']">
<xsl:attribute name="DockPanel.Dock">
<xsl:value-of select="'Left, Right, Top, Bottom'" />
</xsl:attribute>
</xsl:template>
<!-- For every other @dock value, map @dock to DockPanel.dock
and copy value -->
<xsl:template match="@dock">
<xsl:attribute name="DockPanel.Dock">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<!-- Map width attribute to Width -->
<xsl:template match="@width">
<xsl:attribute name="Width">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<!-- Map height attribute to Height -->
<xsl:template match="@height">
<xsl:attribute name="Height">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<!-- Map backcolor to Background -->
<xsl:template match="@backcolor">
<xsl:attribute name="Background">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<!-- Map visible attribute to Visibility -->
<xsl:template match="@visible[. = 'True']">
<xsl:attribute name="Visibility">visible</xsl:attribute>
</xsl:template>
<xsl:template match="@visible[. = 'False']">
<xsl:attribute name="Visibility">hidden</xsl:attribute>
</xsl:template>
<!-- Map text attribute to content -->
<xsl:template match="@text">
<xsl:attribute name="Content">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<!-- Build the border attribute -->
<xsl:template match="@*[starts-with(local-name(), 'border-')][1]">
<xsl:attribute name="BorderThickness">
<!-- Print the border-elements in a comma separated list (non-defined attributes default
to zero) -->
<xsl:call-template name="border-print" />
</xsl:attribute>
</xsl:template>
<!-- Recursive template to group borders in BorderThickness -->
<xsl:template name="border-print">
<xsl:param name="string" select="'left top right bottom'" />
<xsl:param name="parent" select=".." />
<xsl:param name="not-first" select="false()" />
<xsl:if test="$string != ''">
<!-- Obtain next direction -->
<xsl:variable name="direction" select="normalize-space(substring($string, 1, 6))" />
<xsl:variable name="attr" select="$parent/@*[local-name() = concat('border-', $direction)]" />
<!-- Print comma if not the first element -->
<xsl:if test="$not-first"><xsl:text>,</xsl:text></xsl:if>
<!-- Print zero if the attribute cannot be found -->
<xsl:choose>
<!-- Attribute found : print -->
<xsl:when test="$attr">
<xsl:value-of select="$attr" />
</xsl:when>
<!-- Attribute not found: print 0 -->
<xsl:otherwise>
<xsl:text>0</xsl:text>
</xsl:otherwise>
</xsl:choose>
<!-- Recurse -->
<xsl:call-template name="border-print">
<xsl:with-param name="string" select="substring($string, 7)" />
<xsl:with-param name="parent" select="$parent" />
<xsl:with-param name="not-first" select="true()" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="@*" mode="print-border">
<xsl:value-of select="concat(., ',')" />
</xsl:template>
<xsl:template match="@border-bottom" mode="print-border">
<xsl:value-of select="." />
</xsl:template>
<!-- Map font properties -->
<xsl:template match="@font-name">
<xsl:attribute name="FontFamily">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<xsl:template match="@font-size">
<xsl:attribute name="FontSize">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<xsl:template match="@font-style[. = 'Regular']">
<xsl:attribute name="FontStyle">Normal</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
该代码的主要思想是:
您可以使用以下模板来更改元素的名称:
<!-- Transform PanelWrapper to WrapPannel --> <xsl:template match="PanelWrapper"> <WrapPanel> <xsl:apply-templates select="@*|*" /> </WrapPanel> </xsl:template>
它匹配名为PanelWrapper的任何元素,并将其名称更改为WrapPannel。
您可以使用以下模板更改属性名称并保留其值:
<xsl:template match="@font-size"> <xsl:attribute name="FontSize"> <xsl:value-of select="." /> </xsl:attribute> </xsl:template>
它将属性font-size映射到FontSize。
您可以通过匹配属性的名称和值来更改其名称和值,例如:
<xsl:template match="@font-style[. = 'Regular']"> <xsl:attribute name="FontStyle">Normal</xsl:attribute> </xsl:template>
匹配所有属性,例如font-style ='regular'并将其转换为FontStyle ='normal'。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.