2011-03-22 128 views
1

我正在使用以下XSLT将XML转换为XML。我需要验证所需元素的源XML。如果所需节点的兄弟节点的值缺失,则创建一个新节点。 这里是XSLTXSLT XML到XML转换,验证,动态创建节点/元素

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <Data Schema="XML A"> 
      <xsl:apply-templates/> 
     </Data> 
    </xsl:template> 
    <xsl:template match="Attribute[not(Type=following::Type)]"> 
     <Attributes type="{Type}"> 
      <xsl:apply-templates 
       select="../Attribute[Type=current()/Type]" mode="out"/> 
     </Attributes> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="out"> 
     <Attr id="{id}" name="{Name}" value="{Value}"/> 
    </xsl:template> 
    <xsl:template match="Attribute"/> 
</xsl:stylesheet> 

这里是XML

<?xml version="1.0" encoding="windows-1252"?> 
<XML> 
    <Attributes> 
     <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> 
    </Attributes> 
</XML> 

而且如果需要的元素丢失,那么它应该创建下面的XML。我有多个必需的元素。

<?xml version="1.0" encoding="utf-8"?> 
<Data Schema="XML A"> 
    <Attributes type="common"> 
    <Attr id="331" name="Enviornment" value="Development" /> 
    <Attr id="79" name="Retail" value="" /> 
    </Attributes> 
    <Attributes type="category"> 
    <Attr id="402" name="Gender" value="Men" /> 
    </Attributes> 
    <errorCodes> 
    <errorCode>"value for Retail is missing."</errorCode> 
    </errorCodes> 
</Data> 

如果可以使用下面的XSLT来完成,那么它将是一个很大的优点。提前致谢。

<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"> 
       <xsl:sort select="Type" order="descending"/> 
      </xsl:apply-templates> 
     </Data> 
    </xsl:template> 
    <xsl:template 
      match="Attribute[generate-id()=generate-id(key('type', Type)[1])]"> 
     <Attributes type="{Type}"> 
      <xsl:apply-templates 
        select="../Attribute[Type=current()/Type]" mode="out"/> 
     </Attributes> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="out"> 
     <Attr id="{id}" name="{Name}" value="{Value}"/> 
    </xsl:template> 
    <xsl:template match="Attribute"/> 
</xsl:stylesheet> 

回答

6

以下样式:

<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"> 
       <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[generate-id()=generate-id(key('type', Type)[1])]"> 
     <Attributes type="{Type}"> 
      <xsl:apply-templates 
        select="../Attribute[Type=current()/Type]" mode="out"/> 
     </Attributes> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="out"> 
     <Attr id="{id}" name="{Name}" value="{Value}"/> 
    </xsl:template> 
    <xsl:template match="Attribute"/> 
    <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="331" name="Enviornment" value="Development" /> 
     <Attr id="79" name="Retail" value="" /> 
    </Attributes> 
    <Attributes type="category"> 
     <Attr id="402" name="Gender" value="Men" /> 
    </Attributes> 
    <errorCodes> 
     <errorCode>"value for Retail is missing."</errorCode> 
    </errorCodes> 
</Data> 
+0

@Iwburk感谢您的帮助和快速响应。 – JohnXsl 2011-03-22 18:30:10

+0

我还有1个问题。我必须检查一个特定的Attributes/Attribute/Type = ComplexAttr。如果它存在于源代码中,那么我必须在中创建,否则我必须将它默认为某些值。你能指导我如何实现这个输出。 – JohnXsl 2011-03-22 18:38:05

+0

上面的XSLT正在检查所有这些事件。但是,我只想验证所需的特定部分。例如,当节点为/ Attributes/Attribute/Name = Retail时,检查/ Attributes/Attribute/Value的值,如果缺失,则创建一个节点 – JohnXsl 2011-03-22 19:07:26