2017-04-26 4 views
0

나는 XML 문서를 보내고있어 복잡한 중첩 된 요소를 그룹화 :XSLT 1.0 - 나는 XSLT 1.0 변환 속성

<?xml version="1.0" encoding="UTF-8"?> 
<element tag="container"> 
    <data handle="$1"> 
     ... 
    </data> 
    <assignments/> 
    <expression context="$1"> 
     Object_Text 
    </expression> 
    <expression context="$1"> 
     Object_Text 
    </expression> 
    <expression context="$1"> 
     Object_Heading 
    </expression> 
    <element tag="container"> 
     <data handle="$2"> 
      ... 
     </data> 
     <assignments/> 
     <element tag="container"> 
      <data handle="$3"> 
       ... 
      </data> 
      <assignments/> 
      <expression context="$3"> 
       Object_Text 
      </expression> 
     </element> 
     <element tag="container"> 
      ... 
     </element> 
    </element> 
    <element tag="container"> 
     <element tag="container"> 
      <element tag="container"> 
       <expression context="$1"> 
        Object_Text 
       </expression> 
      </element> 
     </element> 
    </element> 
    <element tag="container"> 
    <expression context="$1"> 
     Object_Identifier 
    </expression> 
    </element> 
</element> 

나는 각 표현 유형에 대한 할당을 추가해야합니다 (Object_Text, Object_Heading, ...)를 다음 부모 태그가 포함 된 컨테이너 노드 (모든 컨테이너가 해당 태그를 가지고 있지 않은 경우 해당 태그는 무시해야 함)로 설정하고 표현식의 컨텍스트 값은 컨테이너의 핸들 값에 맞아야합니다. 각 표현식 유형에 대한 할당이 필요하기 때문에 표시되는 양이 아무리 많아도 컨텍스트의 각 유형에 대해 하나의 할당 만 가져야합니다. 그래서 원하는 출력은 다음과 같습니다

<?xml version="1.0" encoding="UTF-8"?> 
<element tag="container"> 
    <data handle="$1"> 
     ... 
    </data> 
    <assignments> <!--Added assignments here (one for each type with @context='$1')--> 
     <assignment name="Object_Text"> 
     </assignment> 
     <assignment name="Object_Heading"> 
     </assignment> 
     <assignment name="Object_Identifier"> 
     </assignment> 
    </assignments> 
    <expression context="$1"> 
     Object_Text 
    </expression> 
    <expression context="$1"> 
     Object_Text 
    </expression> 
    <expression context="$1"> 
     Object_Heading 
    </expression> 
    <element tag="container"> 
     <data handle="$2"> 
      ... 
     </data> 
     <assignments/> 
     <element tag="container"> 
      <data handle="$3"> 
       ... 
      </data> 
      <assignments> <!--Added assignments here (one for each type with @context='$3')--> 
       <assignment name="Object_Text"> 
       </assignment> 
      </assignments> 
      <expression context="$3"> 
       Object_Text 
      </expression> 
     </element> 
     <element tag="container"> 
      ... 
     </element> 
    </element> 

    <element tag="container"> 
    <expression context="$1"> 
     Object_Identifier 
    </expression> 
    </element> 
</element> 

은 현재 내가 Muenchian 그룹화 방법으로 표현 형의 한 그룹 (Object_Text 등)을 얻을 수 있어요. 그러나 제 문제는이 표현식 유형을 해당 속성 @context로 구별 할 수 없다는 것입니다. 따라서 컨테이너에는 동일한 @context에 실제로 포함 된 올바른 표현식에 대한 할당이 포함됩니다.

도움에 감사드립니다. 누군가 원하는 출력을 얻을 수있는 방법을 알고 있습니까? 나는 많은 것을 시도했지만 현재이 일에 대한 경험/지식이 부족합니다.

편집 : XML 문서의 샘플 구조임을 추가해야합니다. 따라서 xslt 함수는 임의적으로 중첩 된 래핑 된 구조의 식을 여러 번 인식해야합니다.

답변

0

, 우리가 제 1 선행-형제 노드 data

<xsl:variable name="dataHandle" select="preceding-sibling::data/@handle"/> 

이의 @handle 속성을 배치합니다 우리가 assignments 노드 아래에 표현

<xsl:key name="kExp" match="expression" use="concat(@context, '|', normalize-space(.))"/> 

에 대한 키를 선언함으로써 시작하자 변수는 노드 assignments에서 사용되고 Muenchian 메서드를 사용합니다 (나는 expre

<xsl:template match="assignments"> 
     <xsl:variable name="dataHandle" select="preceding-sibling::data/@handle"/> 
     <xsl:copy> 
      <xsl:for-each select="../descendant::expression[@context=$dataHandle 
            and generate-id()=generate-id(key('kExp', concat(@context, '|', normalize-space(.)))[1])]"> 
       <assignment name="{normalize-space(.)}"></assignment> 
      </xsl:for-each> 
     </xsl:copy> 
    </xsl:template> 

전체 스타일은 아래와 같다 : ssions는 형제 노드 또는 assignments)의 형제 후손

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:strip-space elements="*"/> 
    <xsl:output indent="yes"/> 

    <xsl:key name="kExp" match="expression" use="concat(@context, '|', normalize-space(.))"/> 


    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="assignments"> 
     <xsl:variable name="dataHandle" select="preceding-sibling::data/@handle"/> 
     <xsl:copy> 
      <xsl:for-each select="../descendant::expression[@context=$dataHandle 
            and generate-id()=generate-id(key('kExp', concat(@context, '|', normalize-space(.)))[1])]"> 
       <assignment name="{normalize-space(.)}"></assignment> 
      </xsl:for-each> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

http://xsltransform.net/a9Giwr에 확인해보기.

+0

답장을 보내 주셔서 감사합니다.이 답변은 저에게 큰 도움이되었으며, 저의 작품을 발전시키기위한 올바른 힌트를 얻었습니다! –

0

이렇게하면 갈 수 있습니다. 이 코드가 고려하지 않은 억압이 있습니다.

<!-- Handle each container that has an assignments node. --> 
    <xsl:template match="element[@tag='container' and .//assignments]"> 
    <!-- Bind to the expressions for this container. --> 
    <xsl:variable name="expressions" select="expression"/> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"> 
     <xsl:with-param name="expressions" select="$expressions"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Create the assignments for each container. --> 
    <xsl:template match="assignments"> 
    <xsl:param name="expressions"/> 
    <xsl:copy> 
     <xsl:for-each select="$expressions"> 
     <xsl:element name="assignment"> 
      <xsl:attribute name="name"> 
      <xsl:value-of select="normalize-space(.)"/> 
      </xsl:attribute> 
     </xsl:element> 
     </xsl:for-each> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Identity template. --> 
    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/>   
    </xsl:copy> 
    </xsl:template>