2014-04-25 3 views
0

일치하는 내용을 기반으로 1로 변환해야하는 2 개의 XML 파일이 있습니다. 주 파일 (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를 가지고 잘못된 것 같습니다이 XSLT를 사용해보십시오. –

답변

0

당신은

<xsl:call-template name="getControlDef"> 
     <xsl:with-param name="type" select="Field[@id='15073']/ListValues/ListValue" /> 
    </xsl:call-template> 

사실 명명 된 템플릿에 매개 변수로 실제 ListValue을 통과 할 수 궁극적 때문에 InstanceRecord 요소가 각 레코드에 대해 생성되기를 원하면 "자산"및 "인스턴스"값을 매개 변수로 전달하면 도움이됩니다

대한-각

<xsl:template name="getControlDef"> 
    <xsl:param name="type" /> 
    <xsl:for-each select="$control_definitions/Records/Record[Field[@id='15086']/ListValues/ListValue=$type]"> 
:
<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에 조건을 추가이

<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"> 

처럼 테스트 것

그리고 for-each 루프에서 다음과 같이 InstanceRecord을 출력합니다.

<InstanceRecord> 
     <Asset> 
     <xsl:value-of select="$asset" /> 
     </Asset> 

... 기타 필드에 대해서도 마찬가지입니다.

<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