2009-11-12 6 views
1

xslt 2.0을 사용하여 xml에서 수량 필드를 합산하려고합니다. 장비 그룹에서 합산하지 않고 여러 항목이있는 장비 중 하나의 수량을 출력합니다. 이 문제를 어떻게 해결할 수 있는지에 대한 아이디어가 있습니까? 여기 그룹화와 함께 XSLT 2.0을 사용하여 수량 합산

<xsl:for-each-group select="//node()" group-by="*[local-name()='lin_id']/text()"> 
    <Results> 
     <xsl:element name="LIN_ID"><xsl:value-of select="*[local-name()='lin_id']"/></xsl:element> 
     <xsl:element name="Count"><xsl:value-of select="sum(current-group()/*[local-name()='qty'])"/></xsl:element> 
    </Results> 
</xsl:for-each-group> 

소스 XML 파일입니다 :

내가 사용하고있어 XSLT 여기

<Equipment> 
    <lin_id>C18312</lin_id> 
    <qty>5</qty> 
    </Equipment> 
    <Equipment> 
    <lin_id>C18345</lin_id> 
    <qty>22</qty> 
    </Equipment> 
    <Equipment> 
    <lin_id>C18378</lin_id> 
    <qty>43</qty> 
    </Equipment> 
    <Equipment> 
    <lin_id>C18378</lin_id> 
    <qty>208</qty> 
    </Equipment> 

그리고하면 출력이 현재 무엇을 : 그래서 당신은

<Results> 
     <LIN_ID>C18312</LIN_Name> 
     <Count>5</Count> 
    </Results> 
    <Results> 
     <LIN_ID>C18345</LIN_Name> 
     <Count>22</Count> 
    </Results> 
     <Results> 
     <LIN_ID>C18378</LIN_Name> 
     <Count>43</Count> 
    </Results> 

그것은 그룹화를하고있는 것을 볼 수 있지만 LIN_ID C18378의 경우 2 개의 엔트리 중 몇 개를 합산하고 251 대신 값 중 하나만 표시합니다.

답변

1

우선 - 무엇을 <xsl:for-each-group select="//node()" >으로해야할까요? 보십시오 : 모든 *[local-name()='…'] 사업 때문에 네임 스페이스입니다

<xsl:for-each-group select="//Equipment" group-by="lin_id"> 
    <Results> 
    <LIN_ID> 
     <xsl:value-of select="current-grouping-key()"/> 
    </LIN_ID> 
    <Count> 
     <xsl:value-of select="sum(current-group()/qty)"/> 
    </Count> 
    </Results> 
</xsl:for-each-group> 

경우, 당신이 바로 네임 스페이스 선언을 얻을 것이 좋습니다. 이것은 불필요하고 경계가 끔찍하기 때문입니다. ;-)

기타 : <xsl:element name="LIN_ID">을 쓸 필요는 없으며 위에 표시된대로 <LIN_ID>을 직접 쓸 수 있습니다.

디버깅 목적을 위해, 당신은 할 수 :

<Count qty_nodes="{count(current-group()/qty)}"> 
    <xsl:value-of select="sum(current-group()/qty)"/> 
</Count> 

보고 얼마나 많은 노드 current-group()/qty 돌아갑니다.

+0

나는 node()가 현재 노드를 가지고 있다고 생각하니? 나는 모른다. 나는이 xslt 파일을 상속 받았고 단지 배울 뿐이므로 나는 bordeline 끔찍한 진술에 아무런 기분을 느끼지 않았다. 나는 aggree해야하고 다른 xslt 파일 중 일부는 네임 스페이스 선언의 혼합을 가지고 있고 다른 것을 모른다. 네가 나에게 준 것이 잘 돌아갔다. 감사! – John81

+0

아니요, // node()는 전체 문서에서 모든 단일 노드 *를 선택합니다. *모두*. XPath에 대해 약간의 독서를해야합니다. ;-) 또한, "경계선 끔찍한"스마일뿐만 아니라 있습니다. 내 대답이 효과적이라면이를 허용으로 표시 할 수 있습니다. Tomalak

+0

Gotcha. 답변으로 표시하고 싶지만 명성이 15 점 뿐이며 10 점 만받습니다. 몇 점 더 남았을 때 돌아와서 할 것입니다. – John81

1

이 변환 : 지정된 입력에 대해 적용

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="/*"> 
     <top> 
      <xsl:for-each-group select="Equipment/lin_id" group-by="."> 
      <Results> 
       <LIN_ID> 
       <xsl:sequence select="current-grouping-key()"/> 
       </LIN_ID> 
       <Count> 
       <xsl:sequence select="sum(current-group()/../qty/xs:integer(.))"/> 
       </Count> 
      </Results> 
      </xsl:for-each-group> 
     </top> 
    </xsl:template> 
</xsl:stylesheet> 

(a wellformed XML 파일로 보정)

:

<t> 
    <Equipment> 
     <lin_id>C18312</lin_id> 
     <qty>5</qty> 
    </Equipment> 
    <Equipment> 
     <lin_id>C18345</lin_id> 
     <qty>22</qty> 
    </Equipment> 
    <Equipment> 
     <lin_id>C18378</lin_id> 
     <qty>43</qty> 
    </Equipment> 
    <Equipment> 
     <lin_id>C18378</lin_id> 
     <qty>208</qty> 
    </Equipment> 
</t> 

가 원하는 결과 생산을

<top> 
    <Results> 
     <LIN_ID>C18312</LIN_ID> 
     <Count>5</Count> 
    </Results> 
    <Results> 
     <LIN_ID>C18345</LIN_ID> 
     <Count>22</Count> 
    </Results> 
    <Results> 
     <LIN_ID>C18378</LIN_ID> 
     <Count>251</Count> 
    </Results> 
</top> 
+0

대신''입니까? – Tomalak

+0

XSLT 2.0에서는 항상 를 사용하고 만 사용하여 텍스트 노드를 생성하는 것이 좋습니다.이 값은 최종 출력에 값이있을 것이라고 확신 할 때만 같습니다. 그렇더라도 값이 * complete * 출력이 아니면 를 사용하는 것이 좋습니다.를 사용했다면, 생성 된 텍스트 노드는 최종 출력을 생성하기 위해 다른 텍스트 노드와 병합되어야합니다. 요약하면 항상 를 사용하십시오. 일부 특수한 경우에 여러 값을 출력하고 @separator 특성을 사용하려고 할 때 를 사용합니다. –

관련 문제