2011-08-17 6 views
0

XSLT를 사용하여 일부 프로비저닝 XML을 SOAP 요청으로 변환하려고합니다. 하지만 XPath 표현식을 완전히 요구하지 않고 유효한 SOAP XML을 생성하는 접근법을 찾는 데 어려움을 겪고 있습니다.XSLT를 사용하여 SOAP XML을 생성 할 때의 문제점

다음은 프로비저닝 XML의 단순화 된 버전입니다.

<CreateOrder> 
    <client_info> 
     <name>John Doe</name> 
     <address> 
      <street1>1211 Lakeview Dr.</street1> 
      <city>New York</city> 
      <state>NY</state> 
      <country>USA</country> 
      <zip>12345</zip> 
     </address> 
    </client_info> 
    <subscriber_number>AAANNNDDDD</subscriber_number> 
</CreateOrder> 

그리고 여기에 사용되는 단순화 된 XSLT가 있습니다.

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" /> 
    <xsl:template match="/"> 
     <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
      <soapenv:Header/> 
      <soapenv:Body> 
       <DirectoryNumber><xsl:value-of select="CreateOrder/subscriber_number"/></DirectoryNumber> 
       <Locale> 
        <xsl:choose> 
         <xsl:when test="CreateOrder/client_info/address/country = 'USA'"> 
          <xsl:text>English (US)</xsl:text> 
         </xsl:when> 
         <xsl:otherwise> 
          <xsl:text>User Defined 1</xsl:text> 
         </xsl:otherwise> 
        </xsl:choose> 
       </Locale> 
      </soapenv:Body> 
     </soapenv:Envelope> 
    </xsl:template> 
</xsl:stylesheet> 

이것은 다음과 같은 XML 출력을 생성합니다. 이것은 내가 원하는/원하는 것입니다. [I 꽤이 인쇄해야한다고 주 -. 내 출력이 실제로없는 줄 바꿈/들여 쓰기 WTH 단지 하나의 라인] 장난으로

<?xml version="1.0" encoding="UTF-8"?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <DirectoryNumber> 
      AAANNNDDDD 
     </DirectoryNumber> 
     <Locale> 
      English (US) 
     </Locale> 
    </soapenv:Body> 
</soapenv:Envelope> 

, 내가 모든 입력에 맞게 <xsl:template match="/">를 사용할 필요가 나타납니다 문서, 그렇지 않으면 SOAP XML을 출력으로 가져 오지 않습니다. XSLT에서 새로운 XML 시퀀스를 생성하는 다른 방법이 있습니까? <xsl:template match="/">가있는 경우

, 나는 (예를 들어, "주소"를 일치 시키려면) 다른 <xsl:template match=..."> 요소를 중첩 할 수 없습니다 그래서 테스트에서 (예 : CreateOrder/client_info/address/country) 전체 XPATH 노드 표현식을 사용합니다. 이것은 작동하지만 특히 우아하지는 않습니다. 실제 예제에서는 오류가 발생하기 쉽습니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?

답변

1

템플릿이 중첩되지 않습니다. 템플릿의 적절한 위치에 <xsl:apply-templates.../>으로 원하는 것을 얻을 수 있습니다. 간단한 예제에서는 경로를 지정하지 않아도되지만 더 크고 복잡한 스타일 시트에서는 많은 재사용 가능한 템플릿을 사용할 수 있습니다.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/"> 
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
     <soapenv:Header/> 
     <soapenv:Body> 
     <DirectoryNumber><xsl:value-of select="CreateOrder/subscriber_number"/></DirectoryNumber> 
     <Locale> 
      <xsl:apply-templates select="CreateOrder/client_info/address/country"/> 
     </Locale> 
     </soapenv:Body> 
    </soapenv:Envelope> 
    </xsl:template> 

    <xsl:template match="country"> 
    <xsl:choose> 
     <xsl:when test=". = 'USA'"> 
     <xsl:text>English (US)</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:text>User Defined 1</xsl:text> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

XSLT를 이해하는 열쇠는 절차 아니에요 ... 당신의 스타일이 컨트롤에없는 실현하는 것입니다. 대신 XSLT 프로세서는 각 입력 태그를 검사 한 다음 스타일 시트에서 일치하는 템플릿을 검색합니다. 일치하는 규칙을 찾아서 적용하면 해당 태그에 대한 처리가 완료됩니다. /과 일치하면 전체 문서가 하나의 템플리트에서 사용됩니다. 다른 템플릿을 호출 할 수있는 유일한 방법은 <xsl:apply-templates select="some xpath"/>을 통해 프로세서에 "some xpath"에 의해 선택된 노드를 사용하여 일치하는 프로세스를 다시 시작하도록하는 것입니다. 스타일 시트의 첫 번째 템플릿이 /과 일치하는 것은 매우 일반적입니다.

+0

감사합니다. XSLT에 익숙하지 않은 나는 무언가를 놓친다는 것을 걱정하고 있었고, 내가하고있는 일을하는 더 좋은 방법이 있었다. 그러므로주의 깊게 설명 된 "그게 네가하는 일"이라는 대답을 듣는 것은 정말로 도움이되었습니다. 그리고 apply-templates 구문을 사용하여 코드 정리/모듈화를 시작합니다. – Torid

관련 문제