如果缺少源,XSLT将检查并创建具有默认值的子节点

时间:2011-03-23 18:30:44

标签: xslt grouping default-value

我需要验证源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>

1 个答案:

答案 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>