2014-04-25 68 views
0

我有2个XML文件,我需要根据匹配转换为1。主文件(Assets.xml)看起来像这样转换多个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

您ControlDefinitions.xml似乎是无效的,因为他们有多个ID,这些ID是相同的。 –

回答

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-每个

<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> 
+0

请评论这与您的要求不符,并将所需输出编辑到问题中 - 这是问题的更多部分,而不是答案。谢谢! – Rup

+0

@ user3571408我已经回复了以前的回答。正如上面“Rup”所解释的那样,正确的回应是留下评论来解释为什么它不能正常工作,并将实际需要的输出添加到原始问题中。 (对我来说,顺便纠正我的XSLT应该不会太难)。 –

+0

对不起,不知道在哪里回复。我已将所需的输出添加到我的原始帖子中。感谢您的帮助! – user3571408