2014-04-25 5 views
0

У меня есть два файла 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> 

Для выхода, мне нужно создать одну запись для каждого актива/Control Definition, которые имеют один и тот же тип (т.е. информацию, физический и т. Д.). Результат должен выглядеть примерно так.

<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 кажется недействительным, поскольку они имеют несколько идентификаторов, которые являются одинаковыми. –

ответ

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: для-каждого

<xsl:template name="getControlDef"> 
    <xsl:param name="type" /> 
    <xsl:for-each select="$control_definitions/Records/Record[Field[@id='15086']/ListValues/ListValue=$type]"> 

И в каждом цикле вы затем выведете свой 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

Смежные вопросы