2013-05-23 4 views
0

일부 요소를 복사하고 일부 요소의 이름을 XML 파일에서 다른 XML 파일로 변경하는 XSLT 템플릿을 만들었습니다.XSLT를 사용하여 요소를 다른 위치로 이동

그러나 요소를 가져 와서 XML 구조의 다른 부분으로 이동하는 방법을 알아낼 수는 없습니다.

나는이 XML 변환 할 :

<Hosts> 
    <Clusters> 
     <Cluster> 
      <Nodes> 
       <WindowsHost/> 
      </Nodes> 
     </Cluster> 
    </Clusters> 
</Hosts> 

에 :

<Hosts> 
    <WindowsHosts> 
     <WindowsHost/> 
    </WindowsHosts> 
</Hosts> 

내 현재 작업 XSLT가 포함

<xsl:template match="/"> 
    <xsl:apply-templates select="*"/> 
</xsl:template> 

<xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:apply-templates select="*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*"> 
    <xsl:apply-templates select="*"/> 
</xsl:template> 

을 ... 그리고 반복 템플릿과 같은 :

<xsl:template match="/Hosts/Clusters/Cluster/Nodes/WindowsHost"> 
    <xsl:copy> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/Hosts/Clusters/Cluster/Nodes/WindowsHost/SomeElement"> 
    <xsl:copy> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

등등. 모든 요소가 복사되지 않고 일부 요소 이름이 변경되기 때문에 복사 할 각 요소에는 자체 템플릿이 있습니다. 그러나 완전한 XPath가 아니라 요소 이름을 변경하는 데 성공했습니다.

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

바울은


는 귀하의 응답은 많이 감사합니다. 그러나 제 예제는 너무 단순한 것으로 생각합니다.

내 기존 XSLT에는 하나의 XML에서 다른 요소로 복사해야하는 모든 요소에 대한 템플릿이 있으므로 많은 템플릿 (약 1000 개)이 있으며 XSLT 파일의 시작 부분에서 어떤 요소도 기본적으로 아무 것도 발생하지 않습니다 . 짧은 이야기 만해도, 나는 당신의 대답에 기술을 시도하지 못했습니다. 아마도 내가 상황을 정확히 보여주지 않았기 때문입니다. 기존

  • 복사입니다

    1. 복사로하지만 스키마에서 다른 위치로 요소 이름을
    2. 복사를 변경 :

      요소에 대한 세 가지 시나리오가 복사되고있다 XSLT 파일은 # 1과 # 2 모두에서 작동합니다. 3 위입니다. 일할 수 없습니다. 여기에 XSLT의 이상이

      <xsl:template match="/"> 
          <xsl:apply-templates select="*"/> 
      </xsl:template> 
      
      <xsl:template match="/*"> 
          <xsl:copy> 
           <xsl:apply-templates select="*"/> 
          </xsl:copy> 
      </xsl:template> 
      
      <xsl:template match="*"> 
          <xsl:apply-templates select="*"/> 
      </xsl:template> 
      
      <xsl:template match="/SAN/ClientProfile"> 
      <!-- copy element as is (working) --> 
          <xsl:copy> 
           <xsl:apply-templates/> 
          </xsl:copy> 
      </xsl:template> 
      
      <xsl:template match="/SAN/ClientProfile/Name"> 
      <!-- copy element but change its name (working) --> 
          <CompanyName> 
           <xsl:apply-templates/> 
          </CompanyName> 
      </xsl:template> 
      
      <xsl:template match="/SAN/EQLHosts/WindowsClusters/Cluster/ClusterNodes/WindowsHost"> 
      <!-- copy to different part of schema (not working) --> 
          <WindowsHost> 
           <xsl:apply-templates/> 
          </WindowsHost> 
      </xsl:template> 
      

      그래서, 내가 /SAN/EQLHosts/WindowsHosts/WindowsHost/SAN/EQLHosts/WindowsClusters/Cluster/ClusterNodes/WindowsHost을 변경하고자하는 파일입니다. 이 요소의 모든 하위 항목은 이미 복사중인 요소와 동일한 방식으로 처리됩니다.

      명확한 설명이 필요합니다. 이 정보가 당신의 대답을 바꿀 지 아니면 내가 단지 밀도인지 여부를 알려주십시오.

  • 답변

    1

    실제로 아무 것도 움직이지 않는 것처럼 보입니다. 일부 요소를 무시하고 새로운 WindowsHosts 요소를 추가하기 만하면됩니다. indentity transform 하나를 가지고 xsl:apply-templates에서 선택한 내용을 /* 템플릿에서 변경하십시오.

    다른 요소의 이름을 바꾸려면 해당 요소와 구체적으로 일치하는 새 템플릿을 추가하기 만하면됩니다. ID 변환은 기존 요소를 수정하지 않고 복사하므로 모든 요소에 대해 템플릿을 가질 필요가 없습니다.

    예 :

    XML 입력

    <Hosts> 
        <Clusters> 
         <Cluster> 
          <Nodes> 
           <WindowsHost/> 
          </Nodes> 
         </Cluster> 
        </Clusters> 
    </Hosts> 
    

    XSLT 1.0

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
        <xsl:output indent="yes"/> 
        <xsl:strip-space elements="*"/> 
    
        <xsl:template match="@*|node()"> 
         <xsl:copy> 
          <xsl:apply-templates select="@*|node()"/> 
         </xsl:copy> 
        </xsl:template> 
    
        <xsl:template match="/*"> 
         <xsl:copy> 
          <WindowsHosts> 
           <xsl:apply-templates select="@*|Clusters/Cluster/Nodes/WindowsHost"/> 
          </WindowsHosts> 
         </xsl:copy> 
        </xsl:template> 
    
    </xsl:stylesheet> 
    

    출력

    ,

    편집

    여기서 이름 변경을 포함하는 예이다. 그것은

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
        <xsl:output indent="yes"/> 
        <xsl:strip-space elements="*"/> 
    
        <!--Identity Transform--> 
        <xsl:template match="@*|node()"> 
         <xsl:copy> 
          <xsl:apply-templates select="@*|node()"/> 
         </xsl:copy> 
        </xsl:template> 
    
        <xsl:template match="/*"> 
         <xsl:copy> 
          <!--Start your select at the first element you need to output and/or modify.--> 
          <xsl:apply-templates select="@*|Clusters/Cluster"/> 
         </xsl:copy> 
        </xsl:template> 
    
        <!--Example rename--> 
        <xsl:template match="Cluster"> 
         <WindowsHosts> 
          <xsl:apply-templates select="@*|Nodes/WindowsHost"/> 
         </WindowsHosts> 
        </xsl:template> 
    
    </xsl:stylesheet> 
    


    편집 # 2

    그래서, 내가 /SAN/EQLHosts/WindowsHosts/WindowsHost/SAN/EQLHosts/WindowsClusters/Cluster/ClusterNodes/WindowsHost을 변경하려면 ... 위의 입력을 사용하여 동일한 출력을 생성합니다. 이 요소 의 모든 하위 항목은 이미 복사중인 요소와 동일한 방식으로 처리됩니다. 이 경우

    , 당신은 당신이 출력에 필요 EQLHosts 다른 아이들이있는 경우 ... EQLHosts에서 WindowsHost

    <xsl:template match="EQLHosts"> 
        <xsl:copy> 
         <xsl:apply-templates select="@*"/> 
         <WindowsHosts> 
          <xsl:apply-templates select="WindowsClusters/Cluster/ClusterNodes/WindowsHost"/> 
         </WindowsHosts> 
        </xsl:copy> 
    </xsl:template> 
    

    을 선택합니다, 당신은 첫 번째 xsl:apply-templates에 그것을 추가 할 수 있습니다. 뭔가 같이 :

    <xsl:apply-templates select="@*|*[not(name()='WindowsClusters')]"/> 
    
    +0

    귀하의 답변에 많은 감사드립니다. 원래 게시물에 추가 정보를 추가했습니다. –

    0

    기존 XSLT 파일이 작동하지 않는 다니엘의 답변을 결합하기 때문에, 난 그냥 XML 구조에서 새로운 장소에 이러한 요소를 이동하기 위해 별도의 XSLT 파일을 만들었습니다. 완벽하게 작동이 파일은 아래와 같다

    ...

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    
    <xsl:template match="@*|node()"> 
        <xsl:copy> 
         <xsl:apply-templates select="@*|node()"/> 
        </xsl:copy> 
    </xsl:template> 
    
    <xsl:template match="EQLHosts"> 
        <xsl:copy> 
         <xsl:apply-templates select="@*"/> 
         <WindowsHosts> 
          <xsl:apply-templates select="WindowsClusters/Cluster/ClusterNodes/WindowsHost"/> 
          <xsl:apply-templates select="WindowsClusters/Cluster/VirtualMachines/WindowsHost"/> 
          <xsl:apply-templates select="WindowsHosts/WindowsHost"/> 
         </WindowsHosts> 
        </xsl:copy> 
    </xsl:template> 
    
    </xsl:stylesheet> 
    

    .... 이 XSLT 파일 에는 모든 요소가 포함되어 있으며 일부는 이동합니다.

    내 기존 XSLT 파일 의 모든 요소를 ​​제외하고 지정된 요소 만 복사합니다. 따라서 두 개의 XSLT 파일을 가지고있는 것이 좋지 않은데, 하나는 다른 파일 바로 다음에 실행됩니다.

    그들을 결합 할 방법이 없다면, 나는 그들을 2로 유지할 것입니다.

    관련 문제