XSLT可追溯性矩阵 - 想法?

时间:2014-01-17 07:28:52

标签: xml xslt uml

所以,我非常精通为正常的一次通过文档转换编写XSLT样式表。 (XML风格A到XML风格B)但是,现在我遇到了一个小问题,遇到了经典的XSLT - 不是程序语言问题,我正在寻找一些想法。

我有一个SysML 1.3需求模型,它将源需求映射到明确的需求,并明确了对分配的系统和测试用例的要求。该工具将生成一些非常简单的矩阵,但我希望能够更好地控制输出。

SysML模型的实际XMI文件是gobbeldygoook难以阅读,所以我将在这里创建一个简化的语法来描述问题。我的数据如下:

<requirement id="REQ01">The device shall heat water</requirement>
<requirement id="REQ02">The device shall fry eggs</requirement>
<requirement id="REQ03">The device shall prepare coffee</requirement>
<requirement id="REQ04">The device shall cook bacon</requirement>
<device id="DEV01">
    <name>Coffee Maker</name>
    <relationship refid="REQ01" type="Satisfy"/>
    <relationship refid="REQ03" type="Satisfy"/>
</device>
<device id="DEV02">
    <name>Frying Pan</name>
    <relationship refid="REQ02" type="Satisfy"/>
    <relationship refid="REQ04" type="Satisfy"/>
</device>

我想要做的是解析此文件并输出CSV文件 有一行是包含所有设备名称的标题 每列需求一行,列中有“X” 对于满足要求的设备。

有关如何最好地利用这些东西的任何建议 与Java完全不同?感谢。

1 个答案:

答案 0 :(得分:0)

这可以通过使用两个单独的模板来实现,这些模板将设备模式属性相匹配,以区分它们,并使用模板中的参数。

首先,因为它涉及在多个地方匹配设备元素,您可以定义一个变量来保存它们

<xsl:variable name="devices" select="//device" />

执行标题行显然是直截了当的。对于每一行,您可以使用apply-templates选择每个需求,但在此模板中,您可以选择设备变量,并将需求ID作为参数传递:

  <xsl:apply-templates select="$devices" mode="requirement">
     <xsl:with-param name="reqid" select="@id" />
  </xsl:apply-templates>

然后,您将有第二个模板与设备匹配,使用此模式,该模板接收参数并检查相关关系是否存在

<xsl:template match="device" mode="requirement">
   <xsl:param name="reqid" />
   <xsl:text>,</xsl:text>
   <xsl:if test="relationship[@refid=$reqid]">X</xsl:if>
</xsl:template>

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="text" />

   <xsl:variable name="devices" select="//device" />
   <xsl:variable name="newline" select="'&#10;'" />

   <xsl:template match="/*">
      <xsl:text>Requirement,</xsl:text>
      <xsl:apply-templates select="$devices" />
      <xsl:value-of select="$newline" />
      <xsl:apply-templates select="requirement" />
   </xsl:template>

   <xsl:template match="device">
      <xsl:if test="position() > 1">,</xsl:if>
      <xsl:value-of select="@id" />
   </xsl:template>

   <xsl:template match="device" mode="requirement">
      <xsl:param name="reqid" />
      <xsl:text>,</xsl:text>
      <xsl:if test="relationship[@refid=$reqid]">X</xsl:if>
   </xsl:template>

   <xsl:template match="requirement">
      <xsl:value-of select="@id" />
      <xsl:apply-templates select="$devices" mode="requirement">
         <xsl:with-param name="reqid" select="@id" />
      </xsl:apply-templates>
      <xsl:value-of select="$newline" />
   </xsl:template>
</xsl:stylesheet>

注意,如果您使用的是XSLT 2.0,则可以使用指定了分隔符的 xsl:value-of 来输出标题行,这样您只需要一个匹配的模板< strong>设备,无需使用该模式。类似的东西:

<xsl:value-of select="$devices/@id" separator="," />