2009-11-25 2 views
1

우리가 다루는 주 파일은 작성자가 매우 구조화되지 않은 DTD를 만든 오래된 XML 파일입니다 (모든 요소는 선택 사항이며 0 또는 파일을 읽는 응용 프로그램은 실제로 필요한만큼 많은 값을 예상합니다. 필자는 알려진 응용 프로그램 요구 사항을 기반으로 XSD를 만들고 XSD에서 정렬되지 않은 요소 목록을 시퀀스로 이동했습니다.XML을 지정된 순서로 변환하십시오. (DTD -> XSD)

이전 XML 파일을 사용할 수있는 간단한 변환 프로세스 (예 : XSLT)가 있으며 새 XSD를 사용하여 유효성을 검사 할 수 있도록 지정된 방법으로 요소를 정렬 할 수 있습니까?

예 :

<Top> 
    <A/> 
    <D/> 
    <B/> 
    <C/> 
    <A/> 
</TOP> 

<Top> 
    <A/> 
    <A/> 
    <B/> 
    <C/> 
    <D/> 
</TOP> 

INTO 또한 어린이는 또한 새로운 순서 기대 순서로 정렬해야 할 요소가있을 수 있습니다. 감사!

답변

6

대신 템플릿 내에서 주문하는 모든 요소를 ​​지정하는 당신이 더 선언적 방식으로 스타일 시트에 포함 된 "조회 목록"을 사용할 수 있습니다

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:my="my-namespace" 
    exclude-result-prefixes="my"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <my:Top> 
    <my:A> 
     <my:AA/> 
     <my:AB/> 
     <my:AC/> 
    </my:A> 
    <my:B/> 
    <my:C/> 
    <my:D/> 
    </my:Top> 
    <xsl:template match="my:*"> 
    <xsl:param name="source"/> 
    <xsl:variable name="current-lookup-elem" select="current()"/> 
    <xsl:for-each select="$source/*[name()=local-name($current-lookup-elem)]"> 
     <xsl:copy> 
     <xsl:apply-templates select="$current-lookup-elem/*"> 
      <xsl:with-param name="source" select="current()"/> 
     </xsl:apply-templates> 
     <xsl:copy-of select="text()"/> 
     </xsl:copy> 
    </xsl:for-each> 
    </xsl:template> 
    <xsl:template match="/Top"> 
    <xsl:apply-templates select="document('')/*/my:*"> 
     <xsl:with-param name="source" select="/"/> 
    </xsl:apply-templates> 
    </xsl:template> 
</xsl:stylesheet> 

이 샘플 :

<Top> 
    <A> 
    <AC/> 
    <AA/> 
    </A> 
    <D/> 
    <B/> 
    <C>yyy</C> 
    <A> 
    <AB/> 
    <AC/> 
    <AA>xxx</AA> 
    </A> 
</Top> 

은 다음을 반환합니다.

<Top> 
    <A> 
     <AA>xxx</AA> 
     <AC/> 
    </A> 
    <A> 
     <AA/> 
     <AB/> 
     <AC/> 
    </A> 
    <B/> 
    <C>yyy</C> 
    <D/> 
</Top> 
+0

나는이 아이디어가 마음에 든다. – Scanningcrew

+0

나는이 방법을 시도해 봤지만 단지 값을 복사하고있다. (나쁜 예이지만 각 요소는 #PCDATA가 비어 있지 않다.) 요소 태그를 인쇄 할 수있는 방법이 있습니까? – Scanningcrew

+1

직전에 를 추가하십시오. 내가 위의 코드를 포함하도록 편집했습니다. – Erlock

1

귀하의 요소를 알파벳 순으로 나타내지 않고 지정한 순서대로 기재하고 싶다고 가정합니다. 이것을 시도하십시오 - XSLT 프로세서 (예 : Saxon)가 필요하며이 파일을 * .xsl로 저장하십시오. 하지만

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output indent="yes" method="xml" version="1.0" /> 

<xsl:template match="Top"> 
    <xsl:copy> 
     <xsl:for-each select="A"> 
     <xsl:copy-of select="." /> 
     </xsl:for-each> 
     <xsl:for-each select="B"> 
     <xsl:copy-of select="." /> 
     </xsl:for-each> 
     <xsl:for-each select="C"> 
     <xsl:copy-of select="." /> 
     </xsl:for-each> 
     <xsl:for-each select="D"> 
     <xsl:copy-of select="." /> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

BIG주의 : 당신이 잘 구성된 XML을하지 않아도 당신의 <Top></TOP> 태그가 일치하지 않으므로, XSLT 프로세서 오류가 발생하고 종료 할 수 있도록 XML은 대소 문자를 구분합니다.

<xsl:copy-of>은 일치하는 요소와 모든 자식 (특성 포함)을 복사합니다. 더 높은 레벨을 재정렬하려면 xsl:copy-ofxsl:copy으로 바꾼 다음 거기에서 비슷한 템플릿을 호출하여 다음 레벨을 순서대로 출력 할 수 있습니다.

+0

매우 명확하고 도움이됩니다. 이것은 굉장합니다! – Scanningcrew

+0

그건 아주 이상한 방법입니다. 왜 단지' ...'? –

관련 문제