2009-12-04 6 views
12

그래,이 질문에 대한 다양한 변형을 보아 왔지만, 내가 해결하려고하는 것에 정확히 답하지 않고, 나는 너무 빽빽 해져 내가하는 일에 다른 대답들 중 하나를 적용하는 법을 보았다. 하나의 XML 문서의 XSLT 변환에 의해 생성 된 항목을 다른 XML 문서로 변환하는 방법

<?xml version="1.0" encoding="utf-8"?> 
<message> 
    <cmd id="api_info"> 
    <api-version>1.0</api-version> 
    <api-build>1.0.0.0</api-build> 
    </cmd> 
</message> 

지금 내가 XSLT 내가이 XML에 적용하고있어 변환을 가지고

나는 다음과 같이 뭔가를 보이는 일부 XML이있다. XSLT는 다음과 유사합니다 내가 얻을 출력은 내가 원하는 기본적으로

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:fo="http://www.w3.org/1999/XSL/Format" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xmlns:fn="http://www.w3.org/2005/xpath-functions" 
       version="2.0"> 

    <xsl:output method="xml" version="1.0" indent="yes"/> 

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

    <xsl:template match="message"> 
     <xsl:element name="message" xmlns="http://www.companyname.com/schemas/product/Version001"> 
      <xsl:apply-templates select="/message/cmd/@id"/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="/message/cmd/@id"> 
     <xsl:variable name="_commandType" select="/message/cmd/@id"/> 
     <xsl:element name="messageHeader"> 
      <xsl:element name="cmdType"> 
       <xsl:value-of select="$_commandType"/> 
      </xsl:element> 
     </xsl:element> 

     <xsl:element name="messageBody"> 
      <xsl:choose> 
       <xsl:when test="$_commandType = 'api_info'"> 
        <xsl:element name="apiInfoBody"> 
         <xsl:element name="apiVersion"> 
          <xsl:value-of select="/message/cmd/api-version"/> 
         </xsl:element> 
         <xsl:element name="apiBuild"> 
          <xsl:value-of select="/message/cmd/api-build"/> 
         </xsl:element> 
        </xsl:element> 
       </xsl:when> 
       <xsl:when test="$_commandType = 'communicationError'"> 
        <xsl:element name="communicationErrorBody"> 
         <xsl:element name="errorCode"> 
          <xsl:value-of select="error-code"/> 
         </xsl:element> 
         <xsl:element name="badCmd"> 
          <xsl:value-of select="bad-cmd"/> 
         </xsl:element> 
        </xsl:element> 
       </xsl:when> 
      </xsl:choose> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

과 같다 다음

<?xml version="1.0" encoding="UTF-8"?> 
<message xmlns="http://www.companyname.com/schemas/product/Version001"> 
    <messageHeader xmlns=""> 
     <cmdType>api_info</cmdType> 
    </messageHeader> 
    <messageBody xmlns=""> 
     <apiInfoBody> 
      <apiVersion>1.0</apiVersion> 
      <apiBuild>1.0.0.0</apiBuild> 
     </apiInfoBody> 
    </messageBody> 
</message> 

하지만 제가 원하지 않는 것은 의 xmlns 있습니다 = " "의 속성은 <입니다. 메시지 헤더 ><messageBody> 요소가 있습니다.

이제 요소에 대해 XSLT에서 네임 스페이스를 명시 적으로 지정하면 원하지 않는 특성이 한 수준 아래로 해당 특성의 자식으로 푸시됩니다.

난 그냥 내 XSL 각 속성을 의 xmlns = ""http://www.companyname.com/schemas/product/Version001 "를 추가 명시 적으로 내 전체 XSLT를 통해 갈 수

:. 요소 정의를,하지만 난 더 우아한 방법이있을 것을 알고 우리 프로그래머 이런 종류의 헛점에 대한 지름길을 갖기에는 너무 게으르다 .XSLT가 단축 된 예제처럼 단순하지 않은 경우, 나는 그렇게하는 것이 바람직하다. 그러나 나는 더 좋은 방법이 있어야한다는 것을 알고있다.

사람이 내가 여기에 누락 알고 있나요?

감사합니다,

AlarmTripper

답변

8

는 사용 제외 - 결과 - 접두어 XSL에를 : 접두사 "# 기본"

이에 대한 W3C의 참조 HERE

편집이다와 스타일 시트 태그 : OK, 내가해야 더 신중하게 XSL을 연구했습니다. 메시지 태그의 xmlns를 스타일 시트 태그까지 이동합니다. 모든 결과 요소를 동일한 네임 스페이스에 넣고 메시지 태그에 네임 스페이스 특성을 갖게합니다. Oxygen/XML에서 이것을 실행하고 원하는 출력을 얻었습니다.

+0

출력 XML을 변경하지 않았습니다. – AlarmTripper

+0

어떤 XSLT 프로세서를 사용하고 있습니까? –

+0

그래, 나는 새 제안이 잘 작동한다는 것을 확인했고 아마도 xmlns 할당을 스타일 시트 요소에 유지하기 때문에 아마도 내 솔루션보다 나은 해결책 일 것입니다. #default 옵션을 사용하면 다른 네임 스페이스 접두사 각각을 제외하지 않아도됩니다. 고마워요. 이 XSLT에 대해 배워야 할 것이 많아서 네임 스페이스가 더 까다로운 측면 중 하나라고 생각합니다. – AlarmTripper

0

좋아, 알아 냈어.

내가 원하는 XSLT는 다음과 같습니다

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:fo="http://www.w3.org/1999/XSL/Format" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xmlns:fn="http://www.w3.org/2005/xpath-functions" 
       exclude-result-prefixes="xsl fo xs fn"> 

    <xsl:output method="xml" version="1.0" indent="yes"/> 

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

    <xsl:template match="message"> 
     <message namespace="http://www.companyname.com/schemas/product/Version001"> 
      <xsl:apply-templates select="/message/cmd/@id"/> 
     </message> 
    </xsl:template> 

    <xsl:template match="/message/cmd/@id"> 
     <xsl:variable name="_commandType" select="/message/cmd/@id"/> 

     <xsl:element name="messageHeader"> 
      <xsl:element name="cmdType"> 
       <xsl:value-of select="$_commandType"/> 
      </xsl:element> 
     </xsl:element> 

     <xsl:element name="messageBody"> 
      <xsl:choose> 
       <xsl:when test="$_commandType = 'api_info'"> 
        <xsl:element name="apiInfoBody"> 
         <xsl:element name="apiVersion"> 
          <xsl:value-of select="/message/cmd/api-version"/> 
         </xsl:element> 
         <xsl:element name="apiBuild"> 
          <xsl:value-of select="/message/cmd/api-build"/> 
         </xsl:element> 
        </xsl:element> 
       </xsl:when> 
       <xsl:when test="$_commandType = 'communicationError'"> 
        <xsl:element name="communicationErrorBody"> 
         <xsl:element name="errorCode"> 
          <xsl:value-of select="error-code"/> 
         </xsl:element> 
         <xsl:element name="badCmd"> 
          <xsl:value-of select="bad-cmd"/> 
         </xsl:element> 
        </xsl:element> 
       </xsl:when> 
      </xsl:choose> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

제외-결과-접두사를 추가 속성을 < XSL이었다 고정 변화 : 스타일 시트 > 요소와 부분 변경 그것은이었다

,536 :

<xsl:template match="message"> 
     <xsl:element name="message" xmlns="http://www.companyname.com/schemas/product/Version001"> 
      <xsl:apply-templates select="/message/cmd/@id"/> 
     </xsl:element> 
    </xsl:template> 

가 대신 다음을 수

<xsl:template match="message"> 
     <message namespace="http://www.companyname.com/schemas/product/Version001"> 
      <xsl:apply-templates select="/message/cmd/@id"/> 
     </message> 
    </xsl:template> 

이제 다시 행복합니다.

아마 더 좋은 방법이 있지만 나에게 도움이 될 것입니다. 앞으로의 제안은 언제나 환영합니다.

0

Jim Garrison (대답) 답변은 필요한 사항입니다. 그러나 게시 한 업데이트 된 스타일 시트는 결과에 "네임 스페이스"특성을 출력하므로 잘 작동하는지 확신 할 수 없습니다.

이해해야 할 핵심 사항은 기본 네임 스페이스가 작동하는 방식입니다. xmlns를 결과로 출력 할 수있는 속성으로 생각하지 마십시오. 대신 스타일 시트의 어휘 적 세부 사항으로 생각하십시오. 그 목적은 그 아래에있는 모든 항목 (요소 자체 및 재정의 될 때까지 하위 항목 모두)에 기본 네임 스페이스를 설정하는 것입니다. (결과적으로 스타일 시트 자체와 구조가 매우 다른 결과 XML에는 동일한 기능이 있습니다.)

스타일 시트의 리터럴 결과 요소 (예 : < 메시지>) 및 < xsl : 요소 > 지침 (예 : < xsl : 요소 이름 = "message">)은 제공된 이름에서 접두어를 사용하지 않으면 기본 네임 스페이스를 사용합니다. 같은 이름 공간을 사용하는 을 모두 사용하려면 Jim Garrison이 제안한대로 스타일 시트 맨 위에 기본 네임 스페이스를 추가해야합니다.

그렇지 않으면 해당 네임 스페이스에없는 일부 요소로 끝날 것이므로 결과에 xmlns = ""(해당 요소의 네임 스페이스 설정 해제)가 포함됩니다.

+0

Thanks Evan! 내가 얻을 수있는 모든 도움에 감사드립니다. 나는 'xmlns'가 attrib처럼 보이는 것을 읽었지 만 그렇지 않습니다. 다시 돌아가서 Jim이 제시 한 것과 일치하는 코드를 변경 했으므로 내 네임 스페이스 태그가 이제 'stylesheet'정의에 올라 있으며 'xmlns : grf = "http : // 블라 브라.com "을 입력 한 다음 내 요소에"grf : "라는 접두사가 붙어 있는지 확인하십시오. 내 회사의 아무도 XSLT 또는 XPATH를 많이 사용하지 않았으므로 여기에서 전문가의 도움을받는 것이 매우 중요합니다. 그래도 그것을 정말로 즐기고있는 m! – AlarmTripper

관련 문제