2011-11-09 3 views
0

지난 며칠 동안 나를 괴롭 히고있는 문제가 있습니다. 꽤 쉬워야하지만, XSLT는 디버그하는 것만 큼 고통 스럽습니다. 우리는가변 요소 이름을 사용하여 XSLT에서 노드 값을 인쇄하려고합니다.

<?xml version="1.0" encoding="UTF-8"?> 
<rfb2> 
    <rfb2_item> 
     <VALDATE>2011-10-23</VALDATE> 
     <FUND_ID>300</FUND_ID> 
     <SEC_ID>34567</SEC_ID> 
    </rfb2_item> 
    <rfb2_item> 
     <VALDATE>2011-1-09</VALDATE> 
     <FUND_ID>700</FUND_ID> 
     <SEC_ID>13587</SEC_ID> 
    </rfb2_item> 
    <rfb2_item> 
     <VALDATE>2011-3-09</VALDATE> 
     <FUND_ID>200</FUND_ID> 
     <SEC_ID>999334</SEC_ID> 
    </rfb2_item> 
<rfb2> 

우리는 각 rfb2_item 값의 쉼표로 구분 된 목록으로 XML을 변환 할 필요가 1.6

입력 XML 자바에서의 Xalan 1.0을 사용하고, 그래서 스타일 시트는 항상 rfb2_item 노드를 반복 처리. 우리는 * $ outputElements는 '경우 예를 들어, 어떤 출력, 그리고 어떤 순서로합니다 rfb2_item (valdate, fund_id, sec_id)의 요소,

<xsl:param name="$outputElements" select="'VALDATE,FUND_ID'"/> 
..outputs... 

2011-10-23,300 
2011-1-09,700 
2011-3-09,200 



<xsl:param name="$outputElements" select="'SEC_ID'"/>  
..outputs... 

34567 
13587 
999334 

전용 케이스 곳을 제어하는 ​​스타일 시트에서 매개 변수를 사용하는 그들이 입력 XML 그래서

<xsl:param name="$outputElements" select="'*'"/> 

..outputs... 

2011-10-23,300,34567 
2011-1-09,700,13587 
2011-3-09,200,999334 

에 나타나는 순서에서 '바로 출력 요소는 내 질문에 우리는 어떻게 $ outputElements 매개 변수를 기반으로 원하는 출력을 생성하는 템플릿을 작성하려면 어떻게해야합니까입니까? 작동 예제는 훌륭한 것입니다 ...

+0

질문을 잊어 버렸습니다. 누군가가 당신을 위해 완전한 xslt를 작성하기를 원하지 않는다면 - 그들은 그것을 할 것입니다. – FailedDev

답변

1

그래, FailedDev 맞습니다. 누군가 당신을 위해 그것을 쓸 것입니다 :

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="text" /> 

    <xsl:param name="outputElements" select=" 'FUND_ID,SEC_ID,VALDATE' " /> 

    <xsl:template match="rfb2_item"> 

     <xsl:for-each select="*[contains($outputElements, local-name()) or $outputElements = '*']"> 
      <xsl:sort select="string-length(substring-before($outputElements, local-name(.)))" /> 
      <xsl:value-of select="text()" /> 
      <xsl:if test="position() != last()"> 
       <xsl:text>,</xsl:text> 
      </xsl:if> 
     </xsl:for-each> 
     <xsl:text>&#13;&#10;</xsl:text> 

    </xsl:template> 

</xsl:stylesheet> 

설명 비트. xsl:for-eachoutputElements 매개 변수에 로컬 이름이 포함되어 있거나 outputElements 매개 변수가 * 인 각 요소를 현재 rfb2_item에 선택합니다 (이 경우 항상 true가됩니다). 해당 로컬 이름 앞에 오는 하위 문자열의 길이를 기준으로 해당 단어를 정렬합니다 (outputElements). 이름이 해당 매개 변수의 뒷부분에서 발생하면이 값이 높아 지므로 매개 변수를 기준으로 정렬됩니다.

예 : 요소 VALDATEsubstring-before 함수에 대해 FUND_ID,SEC_ID을 생성하며, 이는 문자열 길이로 14가됩니다. 이것은 SEC_ID에 대해 얻을 수있는 8보다 높습니다. VALDATE 값은 SEC_ID 다음에 주문됩니다.

xsl:sort 뒤에는 요소 값을 출력하기 위해 간단히 xsl:value-of을 사용합니다. 거기에 여분의 공백을 트림 할 수 있습니다. 마지막으로 위치가 현재 컨텍스트의 마지막 노드 (즉, 정렬 후 xsl:for-each)의 위치와 같지 않은지 여부를 테스트하고, 그렇다면 쉼표를 출력합니다. 이렇게하면 마지막 값 다음에 쉼표를 출력하지 않아도됩니다.

xsl:text을 사용하여 삽입 한 줄 바꿈은 Windows/DOS 규칙을 따릅니다. 캐리지 리턴 + 새 줄 대신 파일에 줄 바꿈 문자 만 사용해야하는 경우 &#13;을 제거하십시오.

CSV 출력에서 ​​쉼표를 이스케이프 처리하지 않습니다. 나는 너에게 맡길거야. XSLT/XPath에서 너무 어려운 것으로 판명되면 extension functions을 사용하여이 작업을 Java에 위임하는 것이 흥미로울 수 있습니다.

+0

안녕하세요? G_H,이 기능은 훌륭합니다. 방금 많은 스트레스를 덜어 주셨습니다. 고마워요. 스타일 시트의 맨 위에 를 추가하여 모든 공백을 제거했습니다. 나는 몇 가지 질문을했다. 분류가 필요한가? 그리고 당신이 문자열 길이에 관해서 논평 한 것은 저에게 우려를줍니다. rfb2_item/E1과 rfb2_item/E2에서와 같이 2 개 이상의 요소가 같은 길이라면 고려해야 할 필요가 있습니까? – raffian

+0

@RaffiM 정렬은 출력 필드가 매개 변수에 의해 결정된 순서대로 있는지 확인하는 것입니다. 요구 사항 중 하나라고 생각합니다. 체크되는 문자열의 길이는 출력되는 요소의 내용이 아닌 ** 매개 변수 ** 인 부분 문자열의 길이입니다. 요소가 매개 변수에 지정된 순서대로 출력되는지 확인하는 것은 속임수입니다. 기본적으로 출력되어야하는 각 요소의 이름 ('FUND_ID','VALDATE' ...)은 다른 수를 산출합니다. 이러한 숫자는 주어진 매개 변수를 기반으로 순서를 설정합니다. –

+0

@G_H ... 그 말이 맞는 ... 마지막 질문은 코드를 더 큰 스타일 시트에 통합하려고 시도하고 있는데 이상한 결과가 발생하고 있습니다. 우리는 그것이 독립적으로 작동한다는 것을 알고 있지만 문제는 우리가 그것을 부르는 방식에 있습니다. "/ *"와 이미 일치하는 다른 템플릿에서 템플릿을 호출하면 (xsl : call-template 사용) 동일한 출력을 생성하기 위해 템플릿 코드가 변경됩니다. – raffian

0

경우에 따라서는 XSLT를 사용하여 XSLT 코드를 생성하거나 수정할 가능성이 있습니다. 매개 변수화를 더 많이 수행 할 수 있습니다. 예를 들어 출력 할 필드, 정렬 방법, 그룹화 여부, 행 선택 기준 등을 제어 할 수 있습니다.

관련 문제