>

이와 비슷한 몇 가지 질문을 찾았지만 필요한 것에 대한 해결책을 '구부리기'위해 고군분투했기 때문에 다시 물어봐서 죄송합니다.

이와 같은 XML이 있습니다 ....

<?xml version="1.0" encoding="UTF-8"?>
<ns:Root
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ns="urn:Test.Namespace"  
    xsi:schemaLocation="urn:Test.Namespace Test1.xsd"
    >
    <ns:element1 id="001">
        <ns:element2 id="001.1" order="1">
            <ns:element3 id="001.1.1" />
        </ns:element2>
        <ns:element2 id="001.2" order="2">
            <ns:element3 id="001.1.2" />
        </ns:element2>        
    </ns:element1>
    <ns:element1 id="003">
        <ns:element2 id="007.0" order="1">
            <ns:element3 id="007.1.1" />
        </ns:element2>
    </ns:element1>
    <ns:element1 id="002">
        <ns:element2 id="002.1" order="3">
            <ns:element3 id="002.1.1" />
        </ns:element2>
        <ns:element2 id="002.2" order="4">
            <ns:element3 id="002.1.2" />
        </ns:element2> 
    </ns:element1>    
</ns:Root>

이 XSLT를 작성했습니다

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns="urn:Test.Namespace"
                >
    <xsl:output indent="no" />
    <xsl:template match="text()[not(string-length(normalize-space()))]"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/">
        <xsl:apply-templates>
            <xsl:sort select="/ns:Root/ns:element1/@id" />
            <xsl:copy-of select="." />
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="ns:element1">
        <xsl:copy-of select="." />
        <xsl:apply-templates />        
    </xsl:template>
    <xsl:template match="ns:element2">
        <xsl:copy-of select="." />
        <xsl:apply-templates />
    </xsl:template>
    <xsl:template match="ns:element3">
        <xsl:copy-of select="." />
    </xsl:template>
</xsl:stylesheet>

(여기에서 XML을 정렬하는 방법 에서 이에 대한 개요를 살펴 보았습니다.

내가하고 싶은 것은이 XSLT를 사용하여 element1의 id 속성으로 원본 XML을 정렬하고 XML을 생성하는 것입니다. 일단 정렬되면 다른 XSLT로 처리하여 최종 결과를 얻을 수 있다는 아이디어입니다.

불행히도 이것은 나에게 어떤 출력도주지 않으므로 정말 바보 같은 오타가 있다고 생각하게합니다. 어딘가에 보이지 않습니다.

도움을 주시면 감사하겠습니다.

감사합니다

  • 답변 # 1

    문제는 여기이 일치하는 템플릿에 있습니다

    <xsl:template match="/">
        <xsl:apply-templates>
            <xsl:sort select="/ns:Root/ns:element1/@id" />
            <xsl:copy-of select="." />
        </xsl:apply-templates>
    </xsl:template>
    
    

    첫째 \  symbol은 문서 레벨 요소와 일치하며 루트ns : Root와 동일하지 않지만 이에 대한 한 수준입니다. 이것이 의미하는 것은 <xsl:apply-templates> 할 때  선택하는 것은ns : root요소이며,이 중 하나만 있으므로 정렬 할 점이 없습니다!

    아마도 시작해야 할 것은 루트 요소를 일치시키고 복사 한 다음 자식을 정렬하는 것입니다.

    <xsl:template match="/*">
        <xsl:copy>
            <!-- Code to select and sort childrens -->
        </xsl:copy>
    </xsl:template>
    
    

    다음 문제는 sort 문입니다. xpath 표현식 /ns:Root/ns:element1/@id 를 사용하고 있습니다. , 그러나 이것은 상대 경로가 아닌 절대 경로이므로 문서에서 첫 번째ns : element1의 @id 속성 만 선택합니다.

    당신이 이미 루트 요소에 위치하고 있다고 가정하면ns : element1요소 만 자식으로 가정하면 이것만으로도 가능합니다

       <xsl:apply-templates>
            <xsl:sort select="@id" />
        </xsl:apply-templates>
    
    

    당신이 가진 마지막 문제는 당신이 <xsl:copy-of select="." /> 를 가지고 있다는 것입니다  xsl : apply-templates의 문은 허용되지 않습니다. 위에 표시된 것처럼xsl : copy를 사용해야합니다.

    아직 알지 못했다면 어떤 식 으로든 변경하지 않는 한 XSLT ID 변환을 사용하여 기존 요소를 복사하는 것이 좋습니다. 이렇게하면 각 특정 유형의 요소에 대한 템플릿을 만들 필요가 없습니다.

    다음 XSLT를 사용해보십시오

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:ns="urn:TestNamespace"                >
        <xsl:output indent="yes" />
        <xsl:strip-space elements="*"/>
        <xsl:template match="text()[not(string-length(normalize-space()))]"/>
        <xsl:template match="/*">
            <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates>
                <xsl:sort select="@id" />
            </xsl:apply-templates>
            </xsl:copy>
        </xsl:template>
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
    </xsl:stylesheet>
    
    

    XML에 적용하면 다음이 출력됩니다

    <ns:Root xmlns:ns="urn:Test.Namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="urn:Test.Namespace Test1.xsd">
       <ns:element1 id="001">
          <ns:element2 id="001.1" order="1">
             <ns:element3 id="001.1.1"/>
          </ns:element2>
          <ns:element2 id="001.2" order="2">
             <ns:element3 id="001.1.2"/>
          </ns:element2>
       </ns:element1>
       <ns:element1 id="002">
          <ns:element2 id="002.1" order="3">
             <ns:element3 id="002.1.1"/>
          </ns:element2>
          <ns:element2 id="002.2" order="4">
             <ns:element3 id="002.1.2"/>
          </ns:element2>
       </ns:element1>
       <ns:element1 id="003">
          <ns:element2 id="007.0" order="1">
             <ns:element3 id="007.1.1"/>
          </ns:element2>
       </ns:element1>
    </ns:Root>
    
    

  • 답변 # 2

    예, 오타입니다. XSLT의 네임 스페이스를 XML에서 사용한 것과 동일한 네임 스페이스로 변경하면됩니다. 또는 그 반대도 마찬가지입니다.

    xmlns:ns="urn:Test.Namespace" -> xmlns:ns="urn:TestNamespace"
    
    

    의견을 바탕으로 한 두 번째 수정은 스와핑 만 포함합니다.

    <xsl:template match="/">
        <xsl:apply-templates>
            <xsl:sort select="/ns:Root/ns:element1/@id" />
            <xsl:copy-of select="." />
        </xsl:apply-templates>
    </xsl:template>
    
    

    to

    <xsl:template match="/">
        <xsl:apply-templates select="ns:Root/ns:element1">
            <xsl:sort select="@id" />
        </xsl:apply-templates>
    </xsl:template>
    
    

  • 이전 java - 이진 트리 구조를 통해 구현 된 이진 힙
  • 다음 html - 3 열 레이아웃 동일 높이