我需要验证源XML并查找Attributes/Attribute/Name
。如果Name = 'ComplexAttr'
,则将其设为Data/Attributes(where @Type='common')/Collection/ComplexAttr
的子节点。如果它不存在,则创建一个具有默认值的节点。但是,我必须使用@Type='ComplexAttr'
验证所有节点,因此它应尽可能动态。
在源XML中,您可以看到我只有一个节点@Type='ComplexAttr'
。但是,在转换后的示例XML中,我有两个<Attr>
节点。这是我想要使用以下XSLT。请让我知道如何做到这一点。
提前谢谢。
XSLT:
<!DOCTYPE xsl:stylesheet [<!ENTITY key "concat(Type[. != 'ComplexAttr'],substring('common',1 div (Type = 'ComplexAttr')))">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="type" match="Attribute" use="&key;"/>
<xsl:template match="/">
<Data Schema="XML A">
<xsl:apply-templates
select="XML/Attributes/Attribute[
generate-id() = generate-id(key('type', &key;)[1])
]">
<xsl:sort select="&key;" order="descending"/>
</xsl:apply-templates>
<errorCodes>
<xsl:apply-templates select="XML/Attributes/Attribute"
mode="errors"/>
</errorCodes>
</Data>
</xsl:template>
<xsl:template match="Attribute">
<xsl:variable name="vCurrent-Grouping-Key" select="&key;"/>
<Attributes type="{$vCurrent-Grouping-Key}">
<xsl:apply-templates select="key('type',$vCurrent-Grouping-Key)"
mode="out"/>
</Attributes>
</xsl:template>
<xsl:template match="Attribute" mode="out" name="makeAttr">
<Attr id="{id}" name="{Name}" value="{Value}"/>
</xsl:template>
<xsl:template match="Attribute[Type='ComplexAttr']" mode="out">
<Collection id="" name="test">
<ComplexAttr refId="0">
<MaskValue />
<xsl:call-template name="makeAttr"/>
</ComplexAttr>
</Collection>
</xsl:template>
<xsl:template match="Attribute" mode="errors"/>
<xsl:template match="Attribute[Value='']" mode="errors">
<errorCode>"value for <xsl:value-of select="Name"/> is missing."</errorCode>
</xsl:template>
</xsl:stylesheet>
源XML:
<?xml version="1.0" encoding="windows-1252"?>
<XML>
<Attributes>
<Attribute>
<id>5</id>
<Name>Buyer ID</Name>
<Type>common</Type>
<Value>Lee</Value>
</Attribute>
<Attribute>
<id>331</id>
<Name>Enviornment</Name>
<Type>common</Type>
<Value>Development</Value>
</Attribute>
<Attribute>
<id>79</id>
<Name>Retail</Name>
<Type>common</Type>
<Value></Value>
</Attribute>
<Attribute>
<id>402</id>
<Name>Gender</Name>
<Type>category</Type>
<Value>Men</Value>
</Attribute>
<Attribute>
<id>1197</id>
<Name>UPC</Name>
<Type>ComplexAttr</Type>
<Value>Testing</Value>
<Path />
</Attribute>
</Attributes>
----转换XML
<Data Schema="XML A">
<Attributes type="common">
<Attr id="5" name="Buyer ID" value="Lee" />
<Attr id="331" name="Enviornment" value="Development" />
<Attr id="79" name="Retail" value="" />
<Collection id="" name="test">
<ComplexAttr refId="0">
<MaskValue />
<Attr id="1197" name="UPC" value="Testing" />
<Attr id="123" name="Size" value="Test" />
</ComplexAttr>
</Collection>
</Attributes>
<Attributes type="category">
<Attr id="402" name="Gender" value="Men" />
</Attributes>
<errorCodes>
<errorCode>"value for Retail is missing."</errorCode>
</errorCodes>
</Data>
答案 0 :(得分:1)
更新:使用更多推送式方法完成样式表(已经很晚了,你知道......)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="type" match="Attribute" use="Type"/>
<xsl:template match="/">
<Data Schema="XML A">
<xsl:apply-templates
select="XML/Attributes/Attribute[
generate-id() = generate-id(key('type', Type)[1])
]">
<xsl:sort select="Type" order="descending"/>
</xsl:apply-templates>
<errorCodes>
<xsl:apply-templates select="XML/Attributes/Attribute"
mode="errors"/>
</errorCodes>
</Data>
</xsl:template>
<xsl:template match="Attribute">
<xsl:if test="Type!='ComplexAttr'">
<Attributes type="{Type}">
<xsl:apply-templates select="key('type',Type)"
mode="out"/>
<xsl:if test="Type='common'">
<Collection id="" name="test">
<ComplexAttr refId="0">
<MaskValue />
<xsl:apply-templates
select="key('type','ComplexAttr')"
mode="out"/>
</ComplexAttr>
</Collection>
</xsl:if>
</Attributes>
</xsl:if>
</xsl:template>
<xsl:template match="Attribute" mode="out">
<Attr id="{id}" name="{Name}" value="{Value}"/>
</xsl:template>
<xsl:template match="Attribute[Type='ComplexAttr']" mode="out">
<Attr id="{id}"
name="{Name}{substring('UPC',1 div not(Name[normalize-space()]))}"
value="{Value}{substring('Testing',1 div not(Value[normalize-space()]))}"/>
</xsl:template>
<xsl:template match="Attribute" mode="errors"/>
<xsl:template match="Attribute[Value='']" mode="errors">
<errorCode>"value for <xsl:value-of select="Name"/> is missing."</errorCode>
</xsl:template>
</xsl:stylesheet>
输出:
<Data Schema="XML A">
<Attributes type="common">
<Attr id="5" name="Buyer ID" value="Lee"/>
<Attr id="331" name="Enviornment" value="Development"/>
<Attr id="79" name="Retail" value=""/>
<Collection id="" name="test">
<ComplexAttr refId="0">
<MaskValue/>
<Attr id="1197" name="UPC" value="Testing"/>
</ComplexAttr>
</Collection>
</Attributes>
<Attributes type="category">
<Attr id="402" name="Gender" value="Men"/>
</Attributes>
<errorCodes>
<errorCode>
"value for Retail is missing."
</errorCode>
</errorCodes>
</Data>