我必须将XML转换为另一种XML,我目前只是一个小问题:
在我的XSLT中,我匹配一个项目,我替换了它的一些子元素,我希望其余部分被apply-template
替换。
示例:
使用此输入:
<?xml version="1.0" encoding="utf-8"?>
<ConfigurationNodes>
<Versions>
<PackagesA Version="1.8" />
<PackageB Version="1.1" />
<PackageC Version="1.7" />
</Versions>
<ConfigurationNode Type="SomeSpecialType">
<Name>MyName</Name>
<Revision>0</Revision>
<Description >The big full description here</Description>
<Status Type="SpecialType2">
<Value>Normal</Value>
<Severity>255</Severity>
</Status>
</ConfigurationNode>
</ConfigurationNodes>
我想以此结束:
<?xml version="1.0" encoding="utf-8"?>
<ConfigurationNodes>
<Versions>
<PackagesA Version="1.8" />
<PackageB Version="1.1" />
<PackageC Version="1.7" />
</Versions>
<Object Name="Configuration" NodeType="SomeOtherType">
<Property Name="Name" Value="MyName" Type="System.String" />
<Property Name="Description" Value="The big full description here" Type="System.String" />
<Property Name="Revision" Value="0" Type="System.Int32" />
<Object Name="Status" Type="SomeOtherSpecialType2">
<Property Name="Value" Value="Normal" Type="System.String" />
<Property Name="Severity" Value="255" Type="System.Int32" />
</Object>
</Object>
</ConfigurationNodes>
目前我有这个XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes" />
<xsl:template match="*[@Type='SomeSpecialType']">
<Object Name="Configuration" NodeType="SomeOtherType">
<Property Name="Name" Value="{Name/text()}" Type="System.String"/>
<Property Name="Description" Value="{Description/text()}" Type="System.String"/>
<Property Name="Revision" Value="{Revision/text()}" Type="System.Int32" />
<xsl:apply-templates select="Status"/>
</Object>
</xsl:template>
<xsl:template match="*[@Type='SpecialType2']">
<Object Name="Status" Type="SomeOtherSpecialType2">
<Property Name="Value" Value="Normal" Type="System.String" />
<Property Name="Severity" Value="255" Type="System.Int32" />
</Object>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
返回给我:
<?xml version="1.0" encoding="utf-8"?>
<ConfigurationNodes>
<Versions>
<PackagesA Version="1.8" />
<PackageB Version="1.1" />
<PackageC Version="1.7" />
</Versions>
<Object Name="Configuration" NodeType="SomeOtherType">
<Property Name="Name" Value="MyName" Type="System.String" />
<Property Name="Description" Value="The big full description here" Type="System.String" />
<Property Name="Revision" Value="0" Type="System.Int32" />
<Name>MyName</Name>
<Revision>0</Revision>
<Description>The big full description here</Description>
<Object Name="Status" Type="SomeOtherSpecialType2">
<Property Name="Value" Value="Normal" Type="System.String" />
<Property Name="Severity" Value="255" Type="System.Int32" /></Object>
</Object>
</ConfigurationNodes>
因此第一个模板中使用的元素仍然被复制(因为我猜它们不匹配)。
我也知道我可以放<xsl:apply-templates select="Status"/>
,这会给我预期的结果,但在我未来的实际案例中,我希望所有不匹配的子元素根据其类型检查另一个模板。
有可能吗?
答案 0 :(得分:0)
尝试制作第一个模板:
<xsl:template match="*[@Type='SomeSpecialType']">
<Object Name="Configuration" NodeType="SomeOtherType">
<Property Name="Name" Value="{Name}" Type="System.String"/>
<Property Name="Description" Value="{Description}" Type="System.String"/>
<Property Name="Revision" Value="{Revision}" Type="System.Int32" />
<xsl:apply-templates select="*[not(self::Name or self::Description or self::Revision)]"/>
</Object>
</xsl:template>
这会将模板应用于当前元素的所有子元素,除了那些已经明确用于填充属性的元素。
我更期待一种我不必指定所有内容的方式 元素
然后我建议你这样试试:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@Type='SomeSpecialType']">
<Object Name="Configuration" NodeType="SomeOtherType">
<xsl:apply-templates/>
</Object>
</xsl:template>
<xsl:template match="*[@Type='SpecialType2']">
<Object Name="Status" Type="SomeOtherSpecialType2">
<Property Name="Value" Value="Normal" Type="System.String" />
<Property Name="Severity" Value="255" Type="System.Int32" />
</Object>
</xsl:template>
<xsl:template match="Name | Description">
<Property Name="{name()}" Value="{.}" Type="System.String"/>
</xsl:template>
<xsl:template match="Revision">
<Property Name="Revision" Value="{.}" Type="System.Int32"/>
</xsl:template>
</xsl:stylesheet>