所以,我非常精通为正常的一次通过文档转换编写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完全不同?感谢。
答案 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="' '" />
<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="," />