我有2个XML文件需要根据匹配转换为1。主文件(Assets.xml)看起来像这样
<Records>
<Record>
<Field id="15072">Server A</Field>
<Field id="15073">
<ListValues>
<ListValue id="65502">Information</ListValue>
</ListValues>
</Field>
<Field id="15083">
<Reference id="205773">Control Instance A</Reference>
</Field>
</Record>
<Record>
<Field id="15072">Server B</Field>
<Field id="15073">
<ListValues>
<ListValue id="65502">Physical</ListValue>
</ListValues>
</Field>
<Field id="15083">
<Reference id="205773">Control Instance A</Reference>
</Field>
</Record>
</Records>
第二个文件(ControlDefinitions.xml)看起来像这样
<Records>
<Record>
<Field id="15056">AR005</Field>
<Field id="15086">
<ListValues>
<ListValue id="65504">Information</ListValue>
</ListValues>
</Field>
</Record>
<Record>
<Field id="15056">AR001</Field>
<Field id="15086">
<ListValues>
<ListValue id="65504">Information</ListValue>
</ListValues>
</Field>
</Record>
<Record>
<Field id="15056">AR002</Field>
<Field id="15086">
<ListValues>
<ListValue id="65504">Physical</ListValue>
</ListValues>
</Field>
</Record>
</Records>
对于输出,我需要为具有相同类型(即信息,物理等)的每个资产/控制定义组合创建单个记录。输出看起来应该是这样的。
<InstanceRecords>
<InstanceRecord>
<Asset>Server A</Asset>
<ControlInstance>Control Instance A</ControlInstance>
<ControlDefinition>AR005</ControlDefinition>
</InstanceRecord>
<InstanceRecord>
<Asset>Server A</Asset>
<ControlInstance>Control Instance A</ControlInstance>
<ControlDefinition>AR002</ControlDefinition>
</InstanceRecord>
</InstanceRecords>
我一直使用的样式表如下。有没有办法做到这一点?任何帮助将不胜感激!谢谢!
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="control_definitions" select="document('../XML/ControlDefinitions.xml')"/>
<xsl:template name="getAsset">
<xsl:value-of select="Field[@id='15072']"/>
</xsl:template>
<xsl:template name="getISMSInstance">
<xsl:value-of select="Field[@id='15083']/Reference"/>
</xsl:template>
<xsl:template name="getControlDef">
<xsl:for-each select="$control_definitions/Records/Record">
<xsl:if test="Field[@id='15086']/ListValues/ListValue='Information'">
<ControlDefinition>
<xsl:value-of select="$control_definitions/Records/Record/Field[@id='15056']"/>
</ControlDefinition>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="Records">
<InstanceRecords>
<xsl:for-each select="Record">
<xsl:if test="Field[@id='15073']/ListValues/ListValue='Information'">
<InstanceRecord>
<Asset>
<xsl:call-template name="getAsset"/>
</Asset>
<ControlInstance>
<xsl:call-template name="getInstance"/>
</ControlInstance>
<xsl:call-template name="getControlDef"/>
</InstanceRecord>
</xsl:if>
</xsl:for-each>
</InstanceRecords>
</xsl:template>
</xsl:stylesheet>
谢谢!这对于匹配ListValues非常有用,但并不能完全满足所需的输出。下面是我想要生成的输出。那可能吗?谢谢!
<InstanceRecords>
<InstanceRecord>
<Asset>Server A</Asset>
<ControlInstance>Control Instance A</ControlInstance>
<ControlDefinition>AR005</ControlDefinition>
</InstanceRecord>
<InstanceRecord>
<Asset>Server A</Asset>
<ControlInstance>Control Instance A</ControlInstance>
<ControlDefinition>AR001</ControlDefinition>
</InstanceRecord>
<InstanceRecord>
<Asset>Server B</Asset>
<ControlInstance>Control Instance A</ControlInstance>
<ControlDefinition>AR002</ControlDefinition>
</InstanceRecord>
</InstanceRecords>
答案 0 :(得分:0)
在与记录匹配的模板中,而不是专门测试“信息”,您可以将实际的 ListValue 作为参数传递给您的命名模板
<xsl:call-template name="getControlDef">
<xsl:with-param name="type" select="Field[@id='15073']/ListValues/ListValue" />
</xsl:call-template>
实际上,因为最终你想要为每条记录生成 InstanceRecord 元素,所以如果你将“资产”和“实例”值作为参数传递,它也会有所帮助
<xsl:call-template name="getControlDef">
<xsl:with-param name="instance"><xsl:call-template name="getInstance"/></xsl:with-param>
<xsl:with-param name="asset"><xsl:call-template name="getAsset"/></xsl:with-param>
<xsl:with-param name="type" select="Field[@id='15073']/ListValues/ListValue" />
</xsl:call-template>
然后在 getControlDef 模板中,你会像这样测试它
<xsl:template name="getControlDef">
<xsl:param name="type" />
<xsl:for-each select="$control_definitions/Records/Record">
<xsl:if test="Field[@id='15086']/ListValues/ListValue=$type">
或者,更好的是,将条件添加到 xsl:for-each
<xsl:template name="getControlDef">
<xsl:param name="type" />
<xsl:for-each select="$control_definitions/Records/Record[Field[@id='15086']/ListValues/ListValue=$type]">
在for-each循环中,您将输出 InstanceRecord ,就像这样......
<InstanceRecord>
<Asset>
<xsl:value-of select="$asset" />
</Asset>
......等等其他领域。
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:variable name="control_definitions" select="document('../XML/ControlDefinitions.xml')"/>
<xsl:template name="getAsset">
<xsl:value-of select="Field[@id='15072']"/>
</xsl:template>
<xsl:template name="getInstance">
<xsl:value-of select="Field[@id='15083']/Reference"/>
</xsl:template>
<xsl:template name="getControlDef">
<xsl:param name="type" />
<xsl:param name="asset" />
<xsl:param name="instance" />
<xsl:for-each select="$control_definitions/Records/Record[Field[@id='15086']/ListValues/ListValue=$type]">
<InstanceRecord>
<Asset>
<xsl:value-of select="$asset" />
</Asset>
<ControlInstance>
<xsl:value-of select="$instance" />
</ControlInstance>
<ControlDefinition>
<xsl:value-of select="Field[@id='15056']"/>
</ControlDefinition>
</InstanceRecord>
</xsl:for-each>
</xsl:template>
<xsl:template match="Records">
<InstanceRecords>
<xsl:for-each select="Record">
<xsl:call-template name="getControlDef">
<xsl:with-param name="instance"><xsl:call-template name="getInstance"/></xsl:with-param>
<xsl:with-param name="asset"><xsl:call-template name="getAsset"/></xsl:with-param>
<xsl:with-param name="type" select="Field[@id='15073']/ListValues/ListValue" />
</xsl:call-template>
</xsl:for-each>
</InstanceRecords>
</xsl:template>
</xsl:stylesheet>