XSLT проверяет и создает дочерний узел со значениями по умолчанию, если souurce отсутствует - PullRequest
0 голосов
/ 23 марта 2011

Мне нужно проверить исходный XML и найти Attributes/Attribute/Name. Если Name = 'ComplexAttr', тогда сделайте его дочерним узлом Data/Attributes(where @Type='common')/Collection/ComplexAttr. А если его нет, то создайте узел со значениями по умолчанию. Однако я должен проверить все узлы с @Type='ComplexAttr', поэтому он должен быть максимально динамичным. В исходном XML вы можете видеть, что у меня есть только 1 узел, где @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 Ответ

1 голос
/ 23 марта 2011

Обновление : завершить таблицу стилей с более широким подходом (уже поздно ...)

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...