2016-11-30 3 views
0

XSLT를 사용하여 XSLT 변환을 컴파일하려하지만 잘못된 클래스 이름을 가진 메소드가 포함되어 있으므로 결과 클래스를 사용할 수 없습니다.XSLTC에서 잘못된 메소드 이름을 사용하여 클래스 생성

설명을 위해

, 여기에 스타일 시트의 (간체) 버전 내가 사용

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ns1="http://some.weird/Namespace#/Definition" 
    xmlns="http://another.strange/Namespace#/Definition"> 

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

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

    <xsl:template match="text()"> 
     <xsl:value-of select="." /> 
    </xsl:template> 
</xsl:stylesheet> 

이것이 달성하려고하는 다른에 XML 파일의 모든 요소의 네임 스페이스를 변경하는 것입니다 하나, 그래서 난 기본적으로 수정 된 신원 변환을 사용하고 있습니다. 그러나 XSLTC는 네임 스페이스 URI의 '#'문자에 문제가있는 것으로 보입니다 (비록 내가 이해할 수는 있지만, 합법적이어야합니다). 위의 컴파일 할 때 XSLTC가 작성하는 클래스 파일은 다음과 같습니다 때문에 (물론 디 컴파일) :

import org.apache.xalan.xsltc.DOM; 
import org.apache.xalan.xsltc.TransletException; 
import org.apache.xalan.xsltc.dom.UnionIterator; 
import org.apache.xalan.xsltc.runtime.AbstractTranslet; 
import org.apache.xalan.xsltc.runtime.BasisLibrary; 
import org.apache.xml.dtm.DTMAxisIterator; 
import org.apache.xml.serializer.SerializationHandler; 

public class ChangeNamespace extends AbstractTranslet { 
    public DOM _dom; 
    protected static String[] _sNamesArray = new String[0]; 
    protected static String[] _sUrisArray = new String[0]; 
    protected static int[] _sTypesArray = new int[0]; 
    protected static String[] _sNamespaceArray = new String[0]; 

    public void buildKeys(DOM var1, DTMAxisIterator var2, SerializationHandler var3, int var4) throws TransletException { 
    } 

    public void topLevel(DOM var1, DTMAxisIterator var2, SerializationHandler var3) throws TransletException { 
     boolean var4 = false; 
    } 

    public void transform(DOM var1, DTMAxisIterator var2, SerializationHandler var3) throws TransletException { 
     this._dom = this.makeDOMAdapter(var1); 
     boolean var4 = false; 
     this.transferOutputSettings(var3); 
     this.buildKeys(this._dom, var2, var3, 0); 
     this.topLevel(this._dom, var2, var3); 
     var3.startDocument(); 
     this.applyTemplates(this._dom, var2, var3); 
     var3.endDocument(); 
    } 

    public void http$colon$$slash$$slash$another$dot$strange$slash$Namespace#$slash$Definition$colon$template$dot$0(DOM var1, DTMAxisIterator var2, SerializationHandler var3, int var4) { 
     String var5 = BasisLibrary.getLocalName(var1.getNodeName(var4)); 
     BasisLibrary.checkQName(var5); 
     String var10001 = BasisLibrary.startXslElement(var5, (String)null, var3, var1, var4); 
     this.applyTemplates(var1, var1.getChildren(var4), var3); 
     var3.endElement(var10001); 
    } 

    public void http$colon$$slash$$slash$another$dot$strange$slash$Namespace#$slash$Definition$colon$template$dot$1(DOM var1, DTMAxisIterator var2, SerializationHandler var3, int var4) { 
     String var5; 
     if((var5 = var1.shallowCopy(var4, var3)) != null) { 
      int var6 = var5.length(); 
      this.applyTemplates(var1, (new UnionIterator(var1)).addIterator(var1.getAxisIterator(2)).addIterator(var1.getAxisIterator(3)).setStartNode(var4), var3); 
      if(var6 != 0) { 
       var3.endElement(var5); 
      } 
     } 

    } 

    public void http$colon$$slash$$slash$another$dot$strange$slash$Namespace#$slash$Definition$colon$template$dot$2(DOM var1, DTMAxisIterator var2, SerializationHandler var3, int var4) { 
     var1.characters(var4, var3); 
    } 

    public final void applyTemplates(DOM var1, DTMAxisIterator var2, SerializationHandler var3) throws TransletException { 
     int var4; 
     while((var4 = var2.next()) >= 0) { 
      switch(var1.getExpandedTypeID(var4)) { 
      case 0: 
      case 9: 
       this.applyTemplates(var1, var1.getChildren(var4), var3); 
       break; 
      case 1: 
       if(var1.getNamespaceName(var4).equals("http://some.weird/Namespace#/Definition")) { 
        this.http$colon$$slash$$slash$another$dot$strange$slash$Namespace#$slash$Definition$colon$template$dot$0(var1, var2, var3, var4); 
        break; 
       } else { 
        var4 = var4; 
       } 
      case 2: 
      case 7: 
      case 8: 
       this.http$colon$$slash$$slash$another$dot$strange$slash$Namespace#$slash$Definition$colon$template$dot$1(var1, var2, var3, var4); 
       break; 
      case 3: 
       this.http$colon$$slash$$slash$another$dot$strange$slash$Namespace#$slash$Definition$colon$template$dot$2(var1, var2, var3, var4); 
      case 4: 
      case 5: 
      case 6: 
      case 10: 
      case 11: 
      case 12: 
      case 13: 
      } 
     } 

    } 

    public ChangeNamespace() { 
     super.namesArray = _sNamesArray; 
     super.urisArray = _sUrisArray; 
     super.typesArray = _sTypesArray; 
     super.namespaceArray = _sNamespaceArray; 
     super.transletVersion = 101; 
    } 
} 

참고 자바 사양에 따라 불법 생성 된 메소드 이름의 일부에 '#'을, 실제로 클래스를 사용하려고 할 때 ClassFormatException이 클래스 로더에 있음을 알 수 있습니다.

내가 어떻게 든 XSLTC를 XSL을 유효하게 컴파일 할 수 있다면 어떤 아이디어라도 될까요? 이 문제를 일으키지 않는 똑같은 일을하기 위해 어떻게 든 내 스타일 시트를 수정할 수 있습니까?

아니요, 네임 스페이스 자체를 변경할 수는 없지만 처리해야하는 외부 시스템에 속하기 때문에 고정되어 있습니다. 영향을받지 않습니다.

+0

XSL 및 XML 입력을 구문 분석하는 동안 이상한 네임 스페이스 (조각에 슬래시 포함)를 더 적절한 URI에 매핑 할 수 있습니다. – aventurin

답변

0

XSLTC의 코드를 디버깅하여 문제를 더 조사한 결과, org.apache.xalan.xsltc.compiler.util.Util 클래스의 escape 메서드에 대한 호출이 발생했습니다.

이 그것을 실제 소스 코드의 모습입니다

(의 Xalan 2.7.2) : 내 경우 문자열에서 메소드 이름을 (처럼 만들려고 할 때 여러 곳에서 호출

public static String escape(String input) { 
    return replace(input, ".-/:", new String[]{"$dot$", "$dash$", "$slash$", "$colon$"}); 
} 

, 네임 스페이스). 비록이 순진 구현이 저의 경우에 설명 된 것처럼 그 목적을 달성하는 데 놀랍도록 불충분합니다. 반환 된 문자열은 더 이상 수정하거나 사용하지 않고 결과 이름이 Java에서 실제로 유효한지 확인하기 위해 사용됩니다.

내 솔루션 (이 나는 것 그것이 좋은 솔루션이 아니기 때문에하지, 여기에 세부로 이동 - 그것은을 위해하지 않은-희미한 마음과 충분한 노하우가 있어야합니다 같은 일을하려고 사람 추가 지시없이 그것을 복제하는 방법, 또는 그런 속임수에서 멀리 떨어져있는 것) 실제로 바이트 코드 조작을 사용하여 위 메서드의 본문을 '#'문자도 처리하는 것으로 대체했습니다. 그것은 필사적 인 움직임이지만, 적어도 지금은 저에게 효과적입니다.