2

我需要使用 XSLT 来映射这种格式的值:

<Package>
<WorkflowProcesses>
    <WorkflowProcess>            
        <Activities>                
            <Activity Name="First Activity" Id="123">                    
            </Activity>       
            <Activity Name="Second Activity" Id="456">                    
            </Activity> 
            <Activity Name="Third Activity" Id="789">                    
            </Activity> 
        </Activities>
        <Transitions>
            <Transition To="789" From="456" Id="ABC">                
            </Transition>  
            <Transition To="456" From="123" Id="XYZ">                    
            </Transition>            
        </Transitions>
    </WorkflowProcess>
</WorkflowProcesses>
</Package>

到这种格式:

<variable type="State">
   <stateId type="Integer">123</stateId>
   <stateName type="String">First Activity</stateName>
   <previousStatesId type="String[]">       
   </previousStatesId>
   <nextStatesId type="String[]">
      <item>456</item>
   </nextStatesId>
</variable>           

<variable type="State">
   <stateId type="Integer">456</stateId>
   <stateName type="String">Second Activity</stateName>
   <previousStatesId type="String[]">
    <item>123</item>
       </previousStatesId>
   <nextStatesId type="String[]">
      <item>789</item>
   </nextStatesId>
</variable>    

<variable type="State">
   <stateId type="Integer">789</stateId>
   <stateName type="String">Third Activity</stateName>
   <previousStatesId type="String[]">
    <item>456</item>
   </previousStatesId>
   <nextStatesId type="String[]">
   </nextStatesId>
</variable>  

我正在努力的部分是从“转换”部分中获取值并将它们分配到正确的区域(“nextStatesId”和“previousStatesId”);其他一切都按预期工作。

到目前为止,我已经成功地使用以下方法映射了 Activity 项:

<xsl:template match="Activities">  
<xsl:apply-templates/>  
</xsl:template>

<xsl:template match="Activity [@Name]">  
<variable type="State">
    <stateId type="Integer"><xsl:value-of select="@Id"/></stateId>
     <stateName type="String"><xsl:value-of select="@Name"/></stateName>
     </variable>
</xsl:template>
</xsl:stylesheet>

我可以使用它来识别所有的 Transition 项目,然后我打算将 Transition 的 id 与当前的 Activity 进行比较,但它在上面的模板中不起作用。我认为这是因为模板没有整个 XML 文件的可见性,因此不理解映射

<xsl:for-each select="Package/WorkflowProcesses/WorkflowProcess/Transitions/Transition">    
      <p>...do some stuff...</p>        
    </xsl:for-each>

通常,如果我在编码,我只需将它们推入两个列表,然后搜索它们。我打算在这里做的只是循环遍历每个活动中的所有转换,并为上一个/下一个状态 id 提供一个简单的“if”语句......但这似乎失败了。

有谁知道实现这一目标的另一种方法?

4

2 回答 2

1

如果你把你的模板放在里面,它会在Activityfor-each中搜索一个孩子 。但是没有。Package/...

您在这里尝试做的是访问根节点。因此在前面加上一个斜杠“ /Package

<xsl:for-each select="/Package/WorkflowProcesses/WorkflowProcess/Transitions/Transition">    
      <p>...do some stuff...</p>        
 </xsl:for-each>

但是,我不建议for-each在这里使用。applay-templates会更合适。尝试:

<xsl:template match="Activity[@Name]">
    <variable type="State">
        <stateId type="Integer">
            <xsl:value-of select="@Id"/>
        </stateId>
        <stateName type="String">
            <xsl:value-of select="@Name"/>
        </stateName>
        <previousStatesId type="String[]">
            <xsl:apply-templates select="//Transition[@To =current()/@Id]" 
                                 mode="from" />
        </previousStatesId>
        <nextStatesId type="String[]">
            <xsl:apply-templates select="//Transition[@From =current()/@Id]" 
                                 mode="to" />
        </nextStatesId>

    </variable>
</xsl:template>

<xsl:template match="Transition" mode="from">
    <item>
        <xsl:value-of select="@From"/>
    </item>
</xsl:template>
<xsl:template match="Transition" mode="to">
    <item>
        <xsl:value-of select="@To"/>
    </item>
</xsl:template>
于 2013-06-07T16:33:46.027 回答
1

这种转换似乎可以满足您的要求。

您的“to this format”格式不正确,因为它没有根元素,所以我添加了一个虚拟<root>元素。

Transition转换使用键通过属性访问元素。

我想知道您是否真的需要在其他空元素previousStatesIdnextStatesId输出元素中使用空格和换行符内容?这种转换会产生自闭合的空元素。如果您需要严格的准确性,那么更改将不难做到。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:key name="transition-from" match="Transition" use="@From"/>
  <xsl:key name="transition-to" match="Transition" use="@To"/>

  <xsl:template match="/">
    <root>
      <xsl:apply-templates select="Package/WorkflowProcesses/WorkflowProcess/Activities/Activity"/>
    </root>
  </xsl:template>

  <xsl:template match="Activity">
    <xsl:variable name="from-here" select="key('transition-from', @Id)"/>
    <xsl:variable name="to-here" select="key('transition-to', @Id)"/>
    <variable type="State">
      <stateId type="Integer">
        <xsl:value-of select="@Id"/>
      </stateId>
      <stateName type="String">
        <xsl:value-of select="@Name"/>
      </stateName>
      <previousStatesId type="String[]">
        <xsl:if test="$to-here">
          <item>
            <xsl:value-of select="$to-here/@From"/>
          </item>
        </xsl:if>
      </previousStatesId>
      <nextStatesId type="String[]">
        <xsl:if test="$from-here">
          <item>
            <xsl:value-of select="$from-here/@To"/>
          </item>
        </xsl:if>
      </nextStatesId>
    </variable>
  </xsl:template>

</xsl:stylesheet>

输出

<root>
   <variable type="State">
      <stateId type="Integer">123</stateId>
      <stateName type="String">First Activity</stateName>
      <previousStatesId type="String[]"/>
      <nextStatesId type="String[]">
         <item>456</item>
      </nextStatesId>
   </variable>
   <variable type="State">
      <stateId type="Integer">456</stateId>
      <stateName type="String">Second Activity</stateName>
      <previousStatesId type="String[]">
         <item>123</item>
      </previousStatesId>
      <nextStatesId type="String[]">
         <item>789</item>
      </nextStatesId>
   </variable>
   <variable type="State">
      <stateId type="Integer">789</stateId>
      <stateName type="String">Third Activity</stateName>
      <previousStatesId type="String[]">
         <item>456</item>
      </previousStatesId>
      <nextStatesId type="String[]"/>
   </variable>
</root>
于 2013-06-07T21:30:48.383 回答