2017-02-16 1 views
1

반복 프로그래밍에서 XSLT 로의 도약에 어려움을 겪고 있습니다. 전에 여기에 한가지 질문을했고 꽤 도움이되었습니다. 그러나 이제는 다른 것을 위해 돌아 왔습니다.XSLT 그룹화 문제

XSLT 1.0을 사용하는 시스템의 주문 가져 오기 파일을 생성하려고합니다. 나는 따라 난 그냥 "예"또는 "아니오"주문 ID와보고 싶어 I 출력을 위해 다음

<orders> 
    <order> 
    <id>1</id> 
    <items> 
     <item> 
      <sku>12345</sku> 
      <addon></addon> 
     </item> 
     <item> 
      <sku>23456</sku> 
      <addon>A</addon> 
     </item> 
     <item> 
      <sku>34567</sku> 
      <addon>B</addon> 
     </item> 
    </items> 
    </order> 
    <order> 
    <id>2</id> 
    <items> 
     <item> 
      <sku>12345</sku> 
      <addon></addon> 
     </item> 
     <item> 
      <sku>23456</sku> 
      <addon></addon> 
     </item> 
    </items> 
    </order> 
</orders> 

아래의 예제 소스 데이터와 함께 몇 가지 논리를 수행하고, 그것을 아래로 단순화 할 필요가 해당 주문에 포함 된 항목에 addon에 대해 정의 된 값이 있는지 여부. 나는 그 값이 무엇인지는 상관하지 않지만, 어떤 항목에 대해서도 공백 이외의 것이 있으면 출력을 yes로하고, 모든 항목이 addon에 대해 비어 있으면 출력에 해당 순서에 대해 no가 표시되어야합니다. 위의 샘플 데이터의 경우, 출력은 단순히 뭔가

첫 번째 추측은

<xsl:key name="opt" match="item/addon" use="concat(ancestor::orders/order/id, '|', .)" /> 

<xsl:template match="/"> 
    <xsl:for-each select="orders/order"> 
     <xsl:value-of select="id" /> 
     <xsl:for-each select="orders/order/item/addon[count(. | key('opt', concat(orders/order/id), '|', .))[1]) = 1]"> 
     <xsl:choose> 
      <xsl:when test=".=''"><xsl:text>Yes</xsl:text></xsl:when>   
      <xsl:otherwise><xsl:text>No</xsl:text></xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each> 
    </xsl:for-each> 
</xsl:template> 

는 내가 완전히 키 구문을 이해하지 못하고 있음을 인정한다

1 Yes 
2 No 

이고 더 사본의 수 있어야/내가 할 수 있었던 것보다/붙여 넣기는 나 자신을 생각해 냈습니다. 위의 시도를 보면 addon이 # 1 순서대로 항목에 다른 값을 가지므로 예를 두 번 출력한다고 생각합니다. 내가 이해하는 프로그래밍 언어로이 일을한다면

, 나는 내가 알고 있기 때문에 XSLT에서 사용할 수있는 무언가로 의사 코드를 변환하는 데 어려움을 겪고있어 것이 의사

bool hasAddon = false; 
foreach(item in items) 
{ 
    if(item.addon != "") 
    { 
     hasAddon = true; 
     break; 
    } 
} 
if(hasAddon) 
    output Yes 
else 
    output No 

같은 것을 사용하십시오 for-each는 XSLT에서 꽤 똑같지는 않습니다. for-each를 깨뜨릴 수는 없으며 변수 값을 한 번만 설정할 수 있습니다. 이러한 옵션이 없으면 필자는 잃어버린 느낌이 들며 키와 재귀 템플릿을 이해하는 데 문제가있어 스스로 솔루션을 찾을 수 있습니다. 모든 도움이 멋질 것입니다

+0

항목이 이미 그룹화되어 있습니다. 그룹에 기준을 충족시키는 항목이 포함되어 있는지 물어보십시오. 루핑이나 재귀가 필요하지 않습니다. –

답변

3

키가 필요한 부분을 이해하지 못 했으므로 간단히 <xsl:choose><xsl:when test="items/item/addon[normalize-space()]">Yes</xsl:when><xsl:otherwise>No</xsl:otherwise></xsl:choose>을 확인할 수 있습니다. <xsl:for-each select="orders/order"> 안에 있습니다.

+0

필자는 필자의 아이템과 그 addon을 그룹으로 묶어서 필드에있을 수있는 다양한 값을 기반으로 여러 번보고 할 필요가 없다고 생각했습니다. 내가 말했듯이, 아마추어 총 여기. item/addon [normalize-space()]가 참조하고있는 것을 설명 할 수 있습니까? 의문의 여지가 없지만 그 일이 무엇인지 이해하고 싶습니다. 주어진 필드에서 값에 대한 일반 검사를 수행하기 위해해야 ​​할 일이 있다면, 그렇습니다. 그렇게하면 효과가 있습니다. – rsly

+1

@DanielHaley, 수정 해 주셔서 감사 드리며, 코드 스 니펫을 수정했습니다. –

+1

''안에는'order' 요소가 문맥 노드이고' (Daniel Haley가 지적한 수정을 사용하여) 공백 이외의 텍스트 내용을 가진'addon' 자손이 있는지 확인하여 명령형 방식으로 루프를 사용하여 수행하고자하는 작업을 단일 표현식으로 검사합니다 . XPath에서 노드를 선택하는 표현식은'xsl : if/when test'와 같은 부울 문맥에서 사용될 때 경로로 적어도 하나의 노드가 선택되면 true로 평가되고, 선택된 노드 집합이 비어 있으면 false로 계산됩니다. –