2010-12-16 3 views
1

플랫폼 : 색슨 9 - XSLT 2.0정렬 XML 요소 순서 XSLT 기반에 외부 문서에 지정된 순서

나는 정기적으로 편집, 업데이트 및 저장해야 3000의 XML 문서를 가지고있다.

프로세스의 일부에는 편집 전에 저장소에서 문서를 체크 아웃하고 편집이 완료되면 정기적으로 게시하는 것이 포함됩니다.

각 문서에는 개별적으로 명명 된 섹션이 있습니다. , 기초 텍스트 요소 내에서

<part> 
     <meta> 
      <place_id>12345</place_id> 
      <place_name>London</place_name> 
      <country_id>GB</country_id> 
      <country_name>United Kingdom</country_name> 
     </meta> 
     <text> 
      <docs>some blurb</docs> 
      <airport>some blurb LGW LHR</airport> 
      <trains>some blurb</trains> 
      <hotels>some blurb</hotels> 
      <health>some blurb</health> 
      <attractions>some blurb</attractions> 
     </text> 
    </part> 

은 거의 100 개의 단원으로 구성되어 있습니다, 모든 편집 팀과, 그들은 가끔의 기본 설정 순서에 마음을 변경할 수 있지만 일반. 어쩌면 일년에 두 번.

현재 편집자 및 게시자를 위해 XML 문서 섹션을 현재 편집자의 편집자에게 제시합니다. 이 순서는 'stdhdg.xml'라는 동적으로 생성 된 외부 문서에 지정된,이 같은 나타납니다 :

<hdgs> 
    <hdg name="docs" newsort="10"/> 
    <hdg name="airport" newsort="30"/> 
    <hdg name="trains" newsort="20"/> 
    <hdg name="hotels" newsort="40"/> 
    <hdg name="health" newsort="60"/> 
    <hdg name="attractions" newsort="50"/> 
</hdgs> 

선호하는 정렬 순서가 HDG/@ newsort에 의해 지정됩니다.

그래서 나는 올바른 순서

<xsl:template match="text"> 
    <xsl:variable name="thetext" select="."/> 
<xsl:variable name="stdhead" select="document('stdhdg.xml')"/> 
    <text> 
     <xsl:for-each select="$stdhead//hdg"> 
      <xsl:sort data-type="number" order="ascending" select="@newsort"/> 
      <xsl:variable name="tagname" select="@name"/> 
      <xsl:variable name="thisnode" select="$thetext/*[local-name() = $tagname]"/> 
      <xsl:apply-templates select="$thisnode"/> 
     </xsl:for-each> 
    </text> 
</xsl:template> 

에서 처리하기 위해 다음과 같이 템플릿을 사용하지만 매우 느리고 성가신 보인다 나는 그것을 속도를 높이기 위해 키를 사용되어야한다고 생각합니다.

이 정렬 작업을 더 간단하게/더 깔끔하게 처리 할 수있는 방법이 있습니까?

(방법을 편집자의 편집을 변경 부탁하지 마십시오. 그건 내 삶의 가치보다 더)

TIA

Feargal

+0

좋은 질문, +1. 모든 편집을하기 전에 다시 정렬해야 할 필요성을 완전히 없애주는 솔루션에 대한 내 대답을 확인하십시오. :) –

답변

0

예, 키는 조회를 가속화한다 . 다음은 개략적 인 내용입니다.

<xsl:stylesheet ...> 

    <xsl:key name="k1" match="text/*" use="local-name()"/> 

    <xsl:variable name="stdhead" select="document('stdhdg.xml')"/> 

    ... 

<xsl:template match="text"> 
    <xsl:variable name="thetext" select="."/> 
    <text> 
     <xsl:for-each select="$stdhead//hdg"> 
      <xsl:sort data-type="number" order="ascending" select="@newsort"/> 
      <xsl:apply-templates select="key('k1', @name, $thetext)"/> 
     </xsl:for-each> 
    </text> 
</xsl:template> 

</xsl:stylesheet> 

모든 것이 브라우저에 직접 입력되어 있으므로 테스트 된 코드가 아닌 접근 방법에 대한 개요로 사용하십시오.

가 두 번째 생각으로 [편집] 나는 당신이 text 요소가 낭비 처리 할 때마다 정렬 생각, 그래서 당신은 텍스트 요소 내에서

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

    <xsl:key name="k1" match="text/*" use="local-name()"/> 

    <xsl:variable name="stdhead" select="document('stdhdg.xml')"/> 

    <xsl:variable name="sorted-headers" as="element(hdg)*"> 
    <xsl:perform-sort select="$stdhead//hdg"> 
     <xsl:sort select="@newsort" data-type="number"/> 
    </xsl:perform-sort> 
    </xsl:variable> 

<xsl:template match="text"> 
    <xsl:variable name="thetext" select="."/> 
    <text> 
     <xsl:for-each select="$sorted-headers"> 
      <xsl:apply-templates select="key('k1', @name, $thetext)"/> 
     </xsl:for-each> 
    </text> 
</xsl:template> 

</xsl:stylesheet> 
+0

+1'xsl : perform-sort' 예를 들어. 큰 문서의 경우에도이 주요 사용법 (컨텍스트 노드 하위 노드 선택)이 메모리 비용을 잊어 버릴 수있는 방식으로 프로세스 속도를 높일 것이라는 것은 의심의 여지가 있습니다. –

+0

@Alejandro : 내 대답을 읽는 것이 좋습니다. :) –

0

에 변경 될 수 거의 100 섹션 그리고 모두 개의 광고 팀과 마찬가지로 명의 사용자가 마음에 드는 순서대로 에 바뀌기도합니다. 어쩌면 일년에 두 번.

. . . . . .

는하지만 매우 느리고 성가신 보인다 나는 문서를이 편집을 위해 제시 할 때마다 정렬 그것을

속도를 잘못된 접근 방식을 키되어 사용되어야한다고 생각합니다.

가장 좋은 해결책은 'stdhdg.xml'문서가 변경되면 일년에 두 번만 정렬하여 저장하는 것입니다 ().

'stdhdg.xml'의 변화가 조직적으로 잘 서로 연관 될 수없는 경우, 다음과 같은 변환을 실행하는 반복 (예를 들어 매일) 일 수 있습니다 :

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="vHeaderLoc" select="'file:///C:/temp/deleteMe/stdhdg.xml'"/> 

<xsl:variable name="vHeaderDoc" select= 
"document($vHeaderLoc)"/> 

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

<xsl:template match= 
    "part/@hash 
      [not(. 
       = 
       string(document('file:///C:/temp/deleteMe/stdhdg.xml')) 
      ) 
      ]"> 
    <xsl:attribute name="hash"> 
    <xsl:value-of select="string($vHeaderDoc)"/> 
    </xsl:attribute> 
</xsl:template> 

<xsl:template match= 
    "/*/text[not(/*/@hash 
       = string(document('file:///C:/temp/deleteMe/stdhdg.xml')) 
       ) 
      ]"> 
    <text> 
    <xsl:apply-templates select="*"> 
    <xsl:sort data-type="number" 
    select="$vHeaderDoc/*/hdg[@name=name(current())]"/> 
    </xsl:apply-templates> 
    </text> 
</xsl:template> 
</xsl:stylesheet> 

주요 내용 XML 문서입니다 (

<part hash="010203040506"> 
    <meta> 
     <place_id>12345</place_id> 
     <place_name>London</place_name> 
     <country_id>GB</country_id> 
     <country_name>United Kingdom</country_name> 
    </meta> 
    <text> 
     <docs>some blurb</docs> 
     <airport>some blurb LGW LHR</airport> 
     <trains>some blurb</trains> 
     <hotels>some blurb</hotels> 
     <health>some blurb</health> 
     <attractions>some blurb</attractions> 
    </text> 
</part> 

과 stdhdg.xml 파일입니다 :) 최상위 요소는 지금 hash 속성을 가지고 있습니다 것은

<hdgs> 
    <hdg name="docs">10</hdg> 
    <hdg name="airport">30</hdg> 
    <hdg name="trains">20</hdg> 
    <hdg name="hotels">40</hdg> 
    <hdg name="health">60</hdg> 
    <hdg name="attractions">50</hdg> 
</hdgs> 

다음 변환은 위의 최신 해시가 새로 분류 메인 컨텐츠 생산 :

<part hash="103020406050"> 
    <meta> 
     <place_id>12345</place_id> 
     <place_name>London</place_name> 
     <country_id>GB</country_id> 
     <country_name>United Kingdom</country_name> 
    </meta> 
    <text> 
     <docs>some blurb</docs> 
     <trains>some blurb</trains> 
     <airport>some blurb LGW LHR</airport> 
     <hotels>some blurb</hotels> 
     <attractions>some blurb</attractions> 
     <health>some blurb</health> 
    </text> 
</part> 

참고 함을 :

  1. 주요 내용 문서의 상단 요소 는 hash 속성을 가지며, 그 값은 stdhdg.xml 문서에있는 정렬 키의 연결입니다.

  2. stdhdg.xml 파일의 형식도 약간 변경되어 키의 연결이 문서의 문자열 값으로 쉽게 생성 될 수 있습니다.

  3. 주 콘텐츠에 저장된 해시가 stdhdg.xml의 sort-keys-concatenation과 동일한 경우 일일 실행 변환은 ID 변환입니다.

  4. 이전 해시가 stdhdg.xml의 정렬 키와 일치하지 않으면 새 해시로 업데이트되고 섹션이 다시 정렬됩니다.