2013-05-22 4 views
0

У меня есть таблицы стилей XSLT, которая выглядит в основном, как:Рабочая XSLT модификация вызывает XSLT прекратить работу

<?xml version="1.0" encoding="utf-8" ?> 
<!-- 
** DEV. NOTES: 
** - NOT TESTED YET! 
--> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <!-- *********** Output type definition ************ --> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 

    <xsl:template match="value" mode="values" /> 

    <!-- ******************************************* VALUE MATCHER ******************************************** --> 
    <xsl:template match="value[@name = 'field_name' or @name = 'field_type' or @name = 'field_dim']" mode="values"> 
     <xsl:variable name="this" select="@name" /> 
     <!-- Create element for the Name node. --> 
     <xsl:if test="$this = 'field_name'"> 
      <xsl:element name="Name"> 
       <xsl:value-of select="text()" /> 
      </xsl:element> 
     </xsl:if> 
     <!-- *************************************************************** --> 
     <!-- Create element for the Type node. --> 
     <xsl:if test="$this = 'field_type'"> 
      <!-- If the type is not a record type. --> 
      <xsl:if test="not(text() = 'record')"> 
       <xsl:element name="Type"> 
        <xsl:value-of select="text()" /> 
       </xsl:element> 
      </xsl:if> 

      <!-- Else if the Type is record type. --> 
      <xsl:if test="text() = 'record'"> 
       <xsl:element name="Type">RECORD</xsl:element> 
      </xsl:if> 
     </xsl:if> 
     <!-- ********************************************************************* --> 
     <!-- Depth & Value for each sub-tree where parenting record is NOT a field --> 
     <xsl:if test="$this = 'field_dim' and parent::record[value[@name = 'field_type' and text() != 'record']]"> 
      <xsl:choose> 
       <xsl:when test="text() = '0'"> 
        <!-- A simple variable is allowed. --> 
        <xsl:element name="Depth">SIMPLE</xsl:element> 
        <xsl:element name="Value">{NS}</xsl:element> 
       </xsl:when> 
       <xsl:when test="text() = '1'"> 
        <!-- The parameter has the type of Array<T>. --> 
        <xsl:element name="Depth">ARRAY</xsl:element> 
        <xsl:element name="Value">{{NS}}</xsl:element> 
       </xsl:when> 
       <xsl:when test="text() = '2'"> 
        <!-- The parameter is some kind of hash table like: java.util.Map<String, Object> --> 
        <xsl:element name="Depth">MAP</xsl:element> 
        <xsl:element name="Value"> 
         <xsl:element name="TKey">{NS}</xsl:element> 
         <xsl:element name="TValue">{NS}</xsl:element> 
        </xsl:element> 
       </xsl:when> 
       <!-- So far no other stuff is allowed. --> 
       <xsl:otherwise /> 
      </xsl:choose> 
     </xsl:if> 
     <!-- ***************************************************************** --> 
     <!-- Depth & Value for each sub-tree where parenting record is a field --> 
     <xsl:if test="$this = 'field_dim' and parent::record[value[@name = 'field_type' and text() = 'record']]"> 
      <xsl:choose> 
       <xsl:when test="text() = '0'"> 
        <!-- A simple variable is allowed. --> 
        <xsl:element name="Depth">SIMPLE</xsl:element> 
       </xsl:when> 
       <xsl:when test="text() = '1'"> 
        <!-- The parameter has the type of Array<T>. --> 
        <xsl:element name="Depth">ARRAY</xsl:element> 
       </xsl:when> 
       <!-- So far no other stuff is allowed. --> 
       <xsl:otherwise /> 
      </xsl:choose> 

      <xsl:element name="Value"> 
       <xsl:apply-templates /> 
      </xsl:element> 
     </xsl:if> 
    </xsl:template> 

    <!-- ********************************************* RECORD MATCHER ********************************************* --> 
    <xsl:template match="record[ancestor::record[@name='sig_in' or @name='sig_out'] and value[@name = 'field_name']]"> 
     <!-- XPath to the actual record item --> 
     <xsl:param name="path" /> 

     <!-- Set the new path --> 
     <xsl:variable name="newpath"> 
      <xsl:value-of select="concat($path,'/', value[@name = 'field_name']/text())" /> 
     </xsl:variable> 

     <!-- XSL:ELEMENT to contain nested records within value tags, so we can handle Array&Map types uniformly. --> 

     <xsl:copy> 
      <xsl:attribute name="path"> 
       <xsl:value-of select="$newpath" /> 
      </xsl:attribute> 

      <xsl:apply-templates mode="values" select="value" /> 

      <xsl:apply-templates> 
       <xsl:with-param name="path" select="$newpath" /> 
      </xsl:apply-templates> 
     </xsl:copy> 

    </xsl:template> 

    <xsl:template match="record[@path]"> 
     <xsl:element name="Value"> 
      <xsl:apply-templates /> 
     </xsl:element> 
    </xsl:template> 

    <!-- ********* Match the inputs ********* --> 
    <xsl:template match="record[@name='sig_in']"> 
     <Inputs name="sig_in"> 
      <xsl:apply-templates> 
       <xsl:with-param name="path" select="'sig_in'" /> 
      </xsl:apply-templates> 
     </Inputs> 
    </xsl:template> 

    <!-- ********* Match the outputs ********* --> 
    <xsl:template match="record[@name='sig_out']"> 
     <Outputs name="sig_out"> 
      <xsl:apply-templates> 
       <xsl:with-param name="path" select="'sig_out'" /> 
      </xsl:apply-templates> 
     </Outputs> 
    </xsl:template> 

    <!-- *********** Container node for the IO records *********** --> 
    <xsl:template match="Values[descendant::record[@name='svc_sig']]"> 
     <Values name="svc_sig"> 
      <xsl:apply-templates select="descendant::record[@name='svc_sig']" /> 
     </Values> 
    </xsl:template> 

    <!-- *** Process node *** --> 
    <xsl:template match="node()"> 
     <xsl:param name="path" /> 

     <xsl:apply-templates select="node()"> 
      <xsl:with-param name="path" select="$path" /> 
     </xsl:apply-templates> 
    </xsl:template> 

</xsl:stylesheet> 

Теперь я выполняю это преобразование из Java в следующем документе:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Values version="2.0"> 
    <value name="svc_type">flow</value> 
    <value name="svc_subtype">default</value> 
    <value name="svc_sigtype">java 3.5</value> 
    <record javaclass="com.wm.util.Values" name="svc_sig"> 
    <record javaclass="com.wm.util.Values" name="sig_in"> 
     <value name="node_type">record</value> 
     <value name="is_public">false</value> 
     <value name="field_type">record</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     <array depth="1" name="rec_fields" type="record"> 
     <record javaclass="com.wm.util.Values"> 
      <value name="node_type">record</value> 
      <value name="node_comment"/> 
      <record javaclass="com.wm.util.Values" name="node_hints"> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
      </record> 
      <value name="is_public">false</value> 
      <value name="field_name">unformatted_email</value> 
      <value name="field_type">record</value> 
      <value name="field_dim">0</value> 
      <value name="nillable">true</value> 
      <value name="form_qualified">false</value> 
      <value name="is_global">false</value> 
      <value name="rec_closed">true</value> 
      <value name="modifiable">true</value> 
      <value name="rec_ref">t00cc_emailresponder.data:email</value> 
     <array depth="1" name="rec_fields" type="record"> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">senders</value> 
     <value name="field_type">string</value> 
     <value name="field_dim">1</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     <value name="is_soap_array_encoding_used">false</value> 
     </record> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">mailBoxNames</value> 
     <value name="field_type">string</value> 
     <value name="field_dim">1</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     <value name="is_soap_array_encoding_used">false</value> 
     </record> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <value name="field_usereditable">true</value> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">subject</value> 
     <value name="field_type">string</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     </record> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <value name="field_usereditable">true</value> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">recvDate</value> 
     <value name="field_type">string</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     </record> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">body</value> 
     <value name="field_type">object</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     </record> 
    </array> 
     </record> 
     </array> 
     <value name="modifiable">true</value> 
    </record> 
    <record javaclass="com.wm.util.Values" name="sig_out"> 
     <value name="node_type">record</value> 
     <value name="is_public">false</value> 
     <value name="field_type">record</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     <array depth="1" name="rec_fields" type="record"> 
     <record javaclass="com.wm.util.Values"> 
      <value name="node_type">record</value> 
      <value name="node_comment"/> 
      <record javaclass="com.wm.util.Values" name="node_hints"> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
      </record> 
      <value name="is_public">false</value> 
      <value name="field_name">formatted_email</value> 
      <value name="field_type">record</value> 
      <value name="field_dim">0</value> 
      <value name="nillable">true</value> 
      <value name="form_qualified">false</value> 
      <value name="is_global">false</value> 
      <value name="rec_closed">true</value> 
      <value name="modifiable">true</value> 
      <value name="rec_ref">t00cc_emailresponder.data:formatted_email</value> 
     <array depth="1" name="rec_fields" type="record"> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <null name="field_usereditable"/> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">@id</value> 
     <value name="field_type">string</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     </record> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <null name="field_usereditable"/> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">sender</value> 
     <value name="field_type">string</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     </record> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <null name="field_usereditable"/> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">mailBoxName</value> 
     <value name="field_type">string</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     </record> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <null name="field_usereditable"/> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">subject</value> 
     <value name="field_type">string</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     </record> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <null name="field_usereditable"/> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">recv_date</value> 
     <value name="field_type">string</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     </record> 
     <record javaclass="com.wm.util.Values"> 
     <value name="node_type">record</value> 
     <value name="node_comment"/> 
     <record javaclass="com.wm.util.Values" name="node_hints"> 
      <null name="field_usereditable"/> 
      <value name="field_largerEditor">false</value> 
      <value name="field_password">false</value> 
     </record> 
     <value name="is_public">false</value> 
     <value name="field_name">body</value> 
     <value name="field_type">string</value> 
     <value name="field_dim">0</value> 
     <value name="nillable">true</value> 
     <value name="form_qualified">false</value> 
     <value name="is_global">false</value> 
     </record> 
    </array> 
     </record> 
     </array> 
     <value name="modifiable">true</value> 
    </record> 
    </record> 
    <value name="node_comment">Service converts email from transport/email to fomatted email. 
Email's sender and receiver will be normalized, unnecessary parts (added by outlook or any other mail client) 
will be removed from email address. 
Email's sent date will be converted to xml datetimeformat. 
Email's body will be mapped from bytestream to string. (convertion happend earlier) 

Input: 
unformatted_email - type of email 

Output: 
formatted_email - type of formatted_email - converted, formatted email. Values in this format will be compatible with 
waiting format fields of INM web service. 
</value> 
    <value name="stateless">no</value> 
    <value name="caching">no</value> 
    <value name="prefetch">no</value> 
    <value name="cache_ttl">15</value> 
    <value name="prefetch_level">1</value> 
    <value name="template">t00cc_emailresponder_functional_mail_formatMailFields</value> 
    <value name="template_type">html</value> 
    <value name="audit_level">off</value> 
    <value name="check_internal_acls">no</value> 
    <value name="icontext_policy">$null</value> 
    <value name="system_service">no</value> 
    <value name="retry_max">0</value> 
    <value name="retry_interval">0</value> 
    <value name="svc_in_validator_options">none</value> 
    <value name="svc_out_validator_options">none</value> 
    <value name="auditoption">0</value> 
    <null name="auditfields_input"/> 
    <null name="auditfields_output"/> 
    <record javaclass="com.wm.util.Values" name="auditsettings"> 
    <value name="document_data">0</value> 
    <value name="startExecution">false</value> 
    <value name="stopExecution">false</value> 
    <value name="onError">true</value> 
    </record> 
    <value name="pipeline_option">1</value> 
    <null name="originURI"/> 
    <value name="modifiable">true</value> 
    <value name="is_public">false</value> 
</Values> 

Для вывод XSLT генерирует следующий XML-документ:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Values name="svc_sig"> 
    <Inputs name="sig_in"> 
     <record path="sig_in/unformatted_email"> 
      <Name>unformatted_email</Name> 
      <Type>RECORD</Type> 
      <Depth>SIMPLE</Depth> 
      <Value/> 
      <record path="sig_in/unformatted_email/senders"> 
       <Name>senders</Name> 
       <Type>string</Type> 
       <Depth>ARRAY</Depth> 
       <Value>{{NS}}</Value> 
      </record> 
      <record path="sig_in/unformatted_email/mailBoxNames"> 
       <Name>mailBoxNames</Name> 
       <Type>string</Type> 
       <Depth>ARRAY</Depth> 
       <Value>{{NS}}</Value> 
      </record> 
      <record path="sig_in/unformatted_email/subject"> 
       <Name>subject</Name> 
       <Type>string</Type> 
       <Depth>SIMPLE</Depth> 
       <Value>{NS}</Value> 
      </record> 
      <record path="sig_in/unformatted_email/recvDate"> 
       <Name>recvDate</Name> 
       <Type>string</Type> 
       <Depth>SIMPLE</Depth> 
       <Value>{NS}</Value> 
      </record> 
      <record path="sig_in/unformatted_email/body"> 
       <Name>body</Name> 
       <Type>object</Type> 
       <Depth>SIMPLE</Depth> 
       <Value>{NS}</Value> 
      </record> 
     </record> 
    </Inputs> 
    <Outputs name="sig_out"> 
     <record path="sig_out/formatted_email"> 
      <Name>formatted_email</Name> 
      <Type>RECORD</Type> 
      <Depth>SIMPLE</Depth> 
      <Value/> 
      <record path="sig_out/formatted_email/@id"> 
       <Name>@id</Name> 
       <Type>string</Type> 
       <Depth>SIMPLE</Depth> 
       <Value>{NS}</Value> 
      </record> 
      <record path="sig_out/formatted_email/sender"> 
       <Name>sender</Name> 
       <Type>string</Type> 
       <Depth>SIMPLE</Depth> 
       <Value>{NS}</Value> 
      </record> 
      <record path="sig_out/formatted_email/mailBoxName"> 
       <Name>mailBoxName</Name> 
       <Type>string</Type> 
       <Depth>SIMPLE</Depth> 
       <Value>{NS}</Value> 
      </record> 
      <record path="sig_out/formatted_email/subject"> 
       <Name>subject</Name> 
       <Type>string</Type> 
       <Depth>SIMPLE</Depth> 
       <Value>{NS}</Value> 
      </record> 
      <record path="sig_out/formatted_email/recv_date"> 
       <Name>recv_date</Name> 
       <Type>string</Type> 
       <Depth>SIMPLE</Depth> 
       <Value>{NS}</Value> 
      </record> 
      <record path="sig_out/formatted_email/body"> 
       <Name>body</Name> 
       <Type>string</Type> 
       <Depth>SIMPLE</Depth> 
       <Value>{NS}</Value> 
      </record> 
     </record> 
    </Outputs> 
</Values> 

Теперь, пока resul t действительно выглядит правильно, есть только одна незначительная «ошибка», которая сводит меня с ума. Я просто не могу представить, что вложенные записи внутри другой записи перемещаются внутри узла Value. Значение, я бы ожидать чего-то большего, как следующее:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Values name="svc_sig"> 
    <Inputs name="sig_in"> 
     <record path="sig_in/unformatted_email"> 
      <Name>unformatted_email</Name> 
      <Type>RECORD</Type> 
      <Depth>SIMPLE</Depth> 
      <Value> 
       <record path="sig_in/unformatted_email/senders"> 
        <Name>senders</Name> 
        <Type>string</Type> 
        <Depth>ARRAY</Depth> 
        <Value>{{NS}}</Value> 
       </record> 
       <record path="sig_in/unformatted_email/mailBoxNames"> 
        <Name>mailBoxNames</Name> 
        <Type>string</Type> 
        <Depth>ARRAY</Depth> 
        <Value>{{NS}}</Value> 
       </record> 
       <record path="sig_in/unformatted_email/subject"> 
        <Name>subject</Name> 
        <Type>string</Type> 
        <Depth>SIMPLE</Depth> 
        <Value>{NS}</Value> 
       </record> 
       <record path="sig_in/unformatted_email/recvDate"> 
        <Name>recvDate</Name> 
        <Type>string</Type> 
        <Depth>SIMPLE</Depth> 
        <Value>{NS}</Value> 
       </record> 
       <record path="sig_in/unformatted_email/body"> 
        <Name>body</Name> 
        <Type>object</Type> 
        <Depth>SIMPLE</Depth> 
        <Value>{NS}</Value> 
       </record> 
      </Value> 
     </record> 
    </Inputs> 
    <Outputs name="sig_out"> 
     <record path="sig_out/formatted_email"> 
      <Name>formatted_email</Name> 
      <Type>RECORD</Type> 
      <Depth>SIMPLE</Depth> 
      <Value> 
       <record path="sig_out/formatted_email/@id"> 
        <Name>@id</Name> 
        <Type>string</Type> 
        <Depth>SIMPLE</Depth> 
        <Value>{NS}</Value> 
       </record> 
       <record path="sig_out/formatted_email/sender"> 
        <Name>sender</Name> 
        <Type>string</Type> 
        <Depth>SIMPLE</Depth> 
        <Value>{NS}</Value> 
       </record> 
       <record path="sig_out/formatted_email/mailBoxName"> 
        <Name>mailBoxName</Name> 
        <Type>string</Type> 
        <Depth>SIMPLE</Depth> 
        <Value>{NS}</Value> 
       </record> 
       <record path="sig_out/formatted_email/subject"> 
        <Name>subject</Name> 
        <Type>string</Type> 
        <Depth>SIMPLE</Depth> 
        <Value>{NS}</Value> 
       </record> 
       <record path="sig_out/formatted_email/recv_date"> 
        <Name>recv_date</Name> 
        <Type>string</Type> 
        <Depth>SIMPLE</Depth> 
        <Value>{NS}</Value> 
       </record> 
       <record path="sig_out/formatted_email/body"> 
        <Name>body</Name> 
        <Type>string</Type> 
        <Depth>SIMPLE</Depth> 
        <Value>{NS}</Value> 
       </record> 
      </Value> 
     </record> 
    </Outputs> 
</Values> 

UPDATE: - Любая запись должна содержать значение 1 узел, со всеми ее полями внутри нее. Таким образом, для установки шаблонов xsl: element были бы значения, чтобы каждое отдельное поле помещалось в свой собственный узел Value, который является «плохим» в текущей ситуации. Вопрос до сих пор не эволюционировал таким образом, что эти записи могут вставляться глубоко внутри друг друга, и каждая запись должна содержать только один узел Value со всеми его полями-подобными записями.

Мое первое впечатление заключалось в том, чтобы изменить скрипт XSLT для создания элемента xsl: как вы можете видеть комментарий в приведенном выше XSLT, но это привело к созданию узла Value для каждого поля записи, который предположил бы, что содержащая запись имеет 1 и фактически находится в массиве.

Спасибо, Joey

+0

Вы действительно считаете, что старый вопрос открыт, не говоря о том, что не так с данными ответами и создавать новые, полезно? http://stackoverflow.com/q/16413367/2115381 –

+0

Если элементы записи должны быть вложены в значение elment, вам нужно использовать 'xsl: apply-templates' внутри вашего' ' –

+0

Абсолютно нет. С текущим решением ничего не получается, почти невозможно обрабатывать то, как он должен обрабатываться в текущем приложении. Я уже пробовал это решение, но еще раз я был недостаточно ясен. Я обновлю вопрос, с полным примером. – Wrath

ответ

1

Ее таблицу стилей на основе ваших с некоторыми изменениями.
Как я уже говорил: если элементы Record должны быть вложены в элементы Value, вам нужно использовать xsl:apply-templates внутри вашего <xsl:element name="Value">.

Пожалуйста, попробуйте следующее:

<?xml version="1.0" encoding="utf-8" ?> 
<!-- 
** DEV. NOTES: 
** - NOT TESTED YET! 
--> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <!-- *********** Output type definition ************ --> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 

    <xsl:template match="value" mode="values" /> 


    <xsl:template match="record" mode="values"> 
     <xsl:param name="path" /> 
     <xsl:apply-templates select="value" mode="values"/> 
     <xsl:variable name ="field_dim" select="value[@name = 'field_dim']/text()" /> 
     <xsl:choose> 
      <xsl:when test="$field_dim = '0'"> 
       <!-- A simple variable is allowed. --> 
       <xsl:element name="Depth">SIMPLE</xsl:element> 
       <xsl:element name="Value"> 
        <xsl:if test="not(descendant::record[value[@name = 'field_name']])"> 
         <xsl:text>{NS}</xsl:text> 
        </xsl:if> 
        <xsl:apply-templates > 
         <xsl:with-param name="path" select="$path" /> 
        </xsl:apply-templates> 
       </xsl:element> 
      </xsl:when> 
      <xsl:when test="$field_dim = '1'"> 
       <!-- The parameter has the type of Array<T>. --> 
       <xsl:element name="Depth">ARRAY</xsl:element> 
       <xsl:element name="Value">{{NS}}</xsl:element> 
      </xsl:when> 
      <xsl:when test="$field_dim = '2'"> 
       <!-- The parameter is some kind of hash table like: java.util.Map<String, Object> --> 
       <xsl:element name="Depth">MAP</xsl:element> 
       <xsl:element name="Value"> 
        <xsl:element name="TKey">{NS}</xsl:element> 
        <xsl:element name="TValue">{NS}</xsl:element> 
       </xsl:element> 
      </xsl:when> 
      <!-- So far no other stuff is allowed. --> 
      <xsl:otherwise /> 
     </xsl:choose> 

    </xsl:template> 

    <!-- ******************************************* VALUE MATCHER ******************************************** --> 
    <xsl:template match="value[@name = 'field_name']" mode="values"> 
     <!-- Create element for the Name node. --> 
     <xsl:element name="Name"> 
      <xsl:value-of select="text()" /> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="value[@name = 'field_type']" mode="values"> 
     <!-- Create element for the Type node. --> 
     <xsl:element name="Type"> 
      <!-- If the type is not a record type. --> 
      <xsl:if test="not(text() = 'record')"> 
        <xsl:value-of select="text()" /> 
      </xsl:if> 
      <!-- Else if the Type is record type. --> 
      <xsl:if test="text() = 'record'">RECORD</xsl:if> 
     </xsl:element> 
    </xsl:template> 



    <!-- ********************************************* RECORD MATCHER ********************************************* --> 
    <xsl:template match="record[ancestor::record[@name='sig_in' or @name='sig_out'] and value[@name = 'field_name']]"> 
     <!-- XPath to the actual record item --> 
     <xsl:param name="path" /> 

     <!-- Set the new path --> 
     <xsl:variable name="newpath"> 
      <xsl:value-of select="concat($path,'/', value[@name = 'field_name']/text())" /> 
     </xsl:variable> 

     <!-- XSL:ELEMENT to contain nested records withi value tags, so we can handle Array&Map types uniformly. --> 

     <xsl:copy> 
      <xsl:attribute name="path"> 
       <xsl:value-of select="$newpath" /> 
      </xsl:attribute> 


      <xsl:apply-templates select="." mode="values" > 
       <xsl:with-param name="path" select="$newpath" /> 
      </xsl:apply-templates> 

     </xsl:copy> 

    </xsl:template> 

    <!-- ********* Match the inputs ********* --> 
    <xsl:template match="record[@name='sig_in']"> 
     <Inputs name="sig_in"> 
      <xsl:apply-templates> 
       <xsl:with-param name="path" select="'sig_in'" /> 
      </xsl:apply-templates> 
     </Inputs> 
    </xsl:template> 

    <!-- ********* Match the outputs ********* --> 
    <xsl:template match="record[@name='sig_out']"> 
     <Outputs name="sig_out"> 
      <xsl:apply-templates> 
       <xsl:with-param name="path" select="'sig_out'" /> 
      </xsl:apply-templates> 
     </Outputs> 
    </xsl:template> 

    <!-- *********** Container node for the IO records *********** --> 
    <xsl:template match="Values[descendant::record[@name='svc_sig']]"> 
     <Values name="svc_sig"> 
      <xsl:apply-templates select="descendant::record[@name='svc_sig']" /> 
     </Values> 
    </xsl:template> 

    <!-- *** Process node *** --> 
    <xsl:template match="node()"> 
     <xsl:param name="path" /> 

     <xsl:apply-templates select="node()"> 
      <xsl:with-param name="path" select="$path" /> 
     </xsl:apply-templates> 
    </xsl:template> 
</xsl:stylesheet> 

, который будет генерировать следующие Outout:

<?xml version="1.0" encoding="UTF-8"?> 
<Values name="svc_sig"> 
    <Inputs name="sig_in"> 
    <record path="sig_in/unformatted_email"> 
     <Name>unformatted_email</Name> 
     <Type>RECORD</Type> 
     <Depth>SIMPLE</Depth> 
     <Value> 
     <record path="sig_in/unformatted_email/senders"> 
      <Name>senders</Name> 
      <Type>string</Type> 
      <Depth>ARRAY</Depth> 
      <Value>{{NS}}</Value> 
     </record> 
     <record path="sig_in/unformatted_email/mailBoxNames"> 
      <Name>mailBoxNames</Name> 
      <Type>string</Type> 
      <Depth>ARRAY</Depth> 
      <Value>{{NS}}</Value> 
     </record> 
     <record path="sig_in/unformatted_email/subject"> 
      <Name>subject</Name> 
      <Type>string</Type> 
      <Depth>SIMPLE</Depth> 
      <Value>{NS}</Value> 
     </record> 
     <record path="sig_in/unformatted_email/recvDate"> 
      <Name>recvDate</Name> 
      <Type>string</Type> 
      <Depth>SIMPLE</Depth> 
      <Value>{NS}</Value> 
     </record> 
     <record path="sig_in/unformatted_email/body"> 
      <Name>body</Name> 
      <Type>object</Type> 
      <Depth>SIMPLE</Depth> 
      <Value>{NS}</Value> 
     </record> 
     </Value> 
    </record> 
    </Inputs> 
    <Outputs name="sig_out"> 
    <record path="sig_out/formatted_email"> 
     <Name>formatted_email</Name> 
     <Type>RECORD</Type> 
     <Depth>SIMPLE</Depth> 
     <Value> 
     <record path="sig_out/formatted_email/@id"> 
      <Name>@id</Name> 
      <Type>string</Type> 
      <Depth>SIMPLE</Depth> 
      <Value>{NS}</Value> 
     </record> 
     <record path="sig_out/formatted_email/sender"> 
      <Name>sender</Name> 
      <Type>string</Type> 
      <Depth>SIMPLE</Depth> 
      <Value>{NS}</Value> 
     </record> 
     <record path="sig_out/formatted_email/mailBoxName"> 
      <Name>mailBoxName</Name> 
      <Type>string</Type> 
      <Depth>SIMPLE</Depth> 
      <Value>{NS}</Value> 
     </record> 
     <record path="sig_out/formatted_email/subject"> 
      <Name>subject</Name> 
      <Type>string</Type> 
      <Depth>SIMPLE</Depth> 
      <Value>{NS}</Value> 
     </record> 
     <record path="sig_out/formatted_email/recv_date"> 
      <Name>recv_date</Name> 
      <Type>string</Type> 
      <Depth>SIMPLE</Depth> 
      <Value>{NS}</Value> 
     </record> 
     <record path="sig_out/formatted_email/body"> 
      <Name>body</Name> 
      <Type>string</Type> 
      <Depth>SIMPLE</Depth> 
      <Value>{NS}</Value> 
     </record> 
     </Value> 
    </record> 
    </Outputs> 
</Values> 

То, что вы должны думать о том, что условия содержания Value в коде ниже:

<xsl:element name="Value"> 
    <xsl:if test="not(descendant::record[value[@name = 'field_name']])"> 
     <xsl:text>{NS}</xsl:text> 
    </xsl:if> 
    <xsl:apply-templates > 
     <xsl:with-param name="path" select="$path" /> 
    </xsl:apply-templates> 
</xsl:element> 

Это генерирует «{NS}», если записей больше нет с именем атрибута = field_name и записи в противном случае.

+0

Большое спасибо. По какой-то причине всякий раз, когда я пытался вызвать xsl: apply-templates, все мои записи nester были в разных узлах Value. Это действительно работает. – Wrath