2016-06-11 2 views
0

없는 루트 노드를 하나 XML 파일 :XSLT를 사용하여 XML을 변환 - 내가 가진

<?xml version="1.0" encoding="utf-8" standalone="no"?> 
<File> 
    <Customer> 
     <LastName>MyLastName</LastName> 
    </Customer> 
    <Cars> 
     <Car> 
      <Color>Blue</Color> 
      <Model>Car2</Model> 
      <Year>1988</Year> 
      <Speed>250</Speed> 
     </Car> 
     <Car> 
      <Color>Green</Color> 
      <Model>Car3</Model> 
      <Year>1989</Year> 
      <Speed>350</Speed> 
     </Car> 
    </Cars> 
</File> 
나는에 대한 XSLT를 사용하여이 변환 할

가 있습니다

<?xml version="1.0" encoding="utf-8"?> 
<File> 
    <Purchaser> 
     <Name>MyLastName</Name> 
    </Purchaser> 
    <vehicles> 
     <vehicle> 
      <vehicleColor>Blue</vehicleColor> 
      <vehicleModel>Car2</vehicleModel> 
      <vehicleYear>1988</vehicleYear> 
      <vehicleSpeed>250</vehicleSpeed> 
     </vehicle> 
     <vehicle> 
      <vehicleColor>Green</vehicleColor> 
      <vehicleModel>Car3</vehicleModel> 
      <vehicleYear>1989</vehicleYear> 
      <vehicleSpeed>350</vehicleSpeed> 
     </vehicle> 
    </vehicles> 
</File> 

XSLT 파일 :

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


    <xsl:template match="File/Customer"> 
     <xsl:element name="Purchaser"> 
      <xsl:element name="Name"> 
       <xsl:value-of select="LastName"/> 
      </xsl:element> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="File/Cars"> 
     <xsl:element name="vehicles"> 
      <xsl:for-each select="Car"> 
       <xsl:element name="vehicle"> 
        <xsl:element name="vehicleColor"> 
         <xsl:value-of select="Color"/> 
        </xsl:element> 
        <xsl:element name="vehicleModel"> 
         <xsl:value-of select="Model"/> 
        </xsl:element> 
        <xsl:element name="vehicleYear"> 
         <xsl:value-of select="Year"/> 
        </xsl:element> 
        <xsl:element name="vehicleSpeed"> 
         <xsl:value-of select="Speed"/> 
        </xsl:element> 
       </xsl:element> 
      </xsl:for-each> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

그러나 출력 파일에 루트 노드가 없습니다. 이 작업을 수행하는 방법?

또한 변환을 수행하는 좋은 방법입니까? 여러 개의 템플릿이 쌓여 있습니까?

답변

0

변환을 수행하는 좋은 방법입니까? 여러 개의 템플릿을 가지고 이 쌓여 있습니까?

이 경우 두 가지 방법 모두 다른 장점이나 단점을 가지지 않으므로 여러 가지 템플릿이나 하나의 템플릿을 사용할 수 있습니다. 개인적으로, 나는 짧고 간단하게 것이고 (당신이 수정없이 복사하는 하나 개의 노드 만 거기에 주로 있기 때문에) 하나의 템플릿에 충실 :

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

<xsl:template match="/File"> 
    <File> 
     <Purchaser> 
      <Name> 
       <xsl:value-of select="Customer/LastName"/> 
      </Name> 
     </Purchaser> 
     <vehicles> 
      <xsl:for-each select="Cars/Car"> 
       <vehicle> 
        <xsl:for-each select="*"> 
         <xsl:element name="vehicle{name()}"> 
          <xsl:value-of select="."/> 
         </xsl:element> 
        </xsl:for-each> 
       </vehicle> 
      </xsl:for-each> 
     </vehicles> 
    </File> 
</xsl:template> 

</xsl:stylesheet> 
+0

감사합니다. ''은 ''입니까? xslt 파일에 노드를 직접 쓸 수 있습니까? –

+0

@ Azerty123 원칙적으로 ** 계산을하지 않는 한 [literal result elements] (https://www.w3.org/TR/xslt/#literal-result-element), 즉 ''을 사용해야합니다. ** 요소의 이름 (네임 스페이스 포함) - 그럼 당신은'xsl : element' 명령을 사용해야 할 것입니다. –

2

내가 신원 변환 템플릿으로 시작하는 것이 좋습니다 것입니다

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

당신은 File 요소처럼 변환하려는 한 다음 템플릿

같은 변환을하고 추가 할 수 있습니다하지 않는 복사 노드
<xsl:template match="Customer"> 
    <Purchaser> 
    <xsl:apply-templates/> 
    </Purchaser> 
</xsl:template> 

<xsl:template match="LastName"> 
    <Name> 
    <xsl:apply-templates/> 
    </Name> 
</xsl:template> 

<xsl:template match="Cars"> 
    <vehicles> 
    <xsl:apply-templates/> 
    </vehicles> 
</xsl:template> 

<xsl:template match="Car"> 
    <vehicle> 
    <xsl:apply-templates/> 
    </vehicle> 
</xsl:template> 

<xsl:template match="Car/*"> 
    <xsl:element name="vehicle{local-name()}"> 
    <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

등등. 보시다시피, 나는 런타임시 이름 및/또는 네임 스페이스를 계산할 필요가있을 때만 필요하기 때문에 좀 더 자세한 설명이있는 xsl:element 대신에 대부분의 장소에서 리터럴 결과 요소를 사용했습니다.

+0

감사하지만 난처럼 내 출력의 각 노드 이름을 정의 할 내 'XSLT'. 제 XSLT 구조를 유지할 것입니다 –

+2

당신은 "이것은 변형을 만드는 좋은 방법입니까?"라고 물었습니다. 좋은, 잘 구조화되고, 유연하며, 확장 가능하고 쉬운 방법을 보여주기 위해 노력하고 있습니다. 당신이 복잡한 방식을 선호한다면 그것은 당신에게 달려 있습니다. 나는 왜 ' ...'과 같은 리터럴 결과 엘리먼트를 사용하면 엘리먼트 이름을 정의 할 수 없다는 것을 알지 못한다.' ... 똑같은 것을 성취한다. –

+0

Ok, 감사합니다, 그냥 내 XSLT 파일에서 루트 노드를 정의하는 방법? –

관련 문제