2012-04-21 5 views
3

수정해야 할 XML 파일이 있습니다. 먼저 그룹을 작성한 다음 두 노드를 제외해야합니다.XPath/XQuery - 일부 요소를 제외하고 노드 선택

<root> 
    { 
    for $color in distinct-values(doc('cars.xml')//cars/car/color) 
    let $car := doc('cars.xml')//cars/car 
    return <appearance color="{$color}"> 
      { $car[color eq $color ] } 
      </appearance> 
    } 
</root> 

내가 얻을 :

<cars> 
    <car> 
     <make>Toyota</make> 
     <model>Camry</model> 
     <color>White</color> 
     <price>123</price> 
    </car> 
    <car> 
     <make>Honda</make> 
     <model>Accord</model> 
     <color>White</color> 
     <price>423</price> 
    </car> 
</cars> 

다음은 변환을 수행 내 코드입니다

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <appearance color="White"> 
     <car> 
      <make>Toyota</make> 
      <model>Camry</model> 
      <color>White</color> 
      <price>123</price> 
     </car> 
     <car> 
      <make>Honda</make> 
      <model>Accord</model> 
      <color>White</color> 
      <price>423</price> 
     </car> 
    </appearance> 
</root> 

이 내가 한 가지 문제를 제외하고 필요의 95 %를 않습니다. 그룹화를 유지하면서 최종 XML에서 노드 "색"과 "가격"을 제외해야합니다.

나는 내 return 문에서 다음을 수행하려고 : {$ 자동차 [컬러의 EQ $ 색상]/*하지 (자체 :: 가격)] [하지 (자체 :: 색상)]}

일의 종류 그러나 그것은 완전하게 "차"요소를 삭제한다!! 어떤 충고? 이 도움이

<root> 
{ 
    let $cars-doc := doc('cars.xml') 
    let $color := distinct-values($cars-doc//cars/car/color) 
    return 
     for $carcolor in $color 
     return 
      <appearance color="{$carcolor}"> 
      { 
       for $car in $cars-doc//cars/car 
       where $car/color = $carcolor 
       return 
        <car> 
        {$car/*[not(self::color or self::price)]} 
        </car> 
      } 
      </appearance> 
} 
</root> 

희망 :

답변

5

이보십시오.

0

XPath에서는 새 노드를 만들 수 없습니다. 입력 문서에 이미 존재하는 노드를 변경하지 않거나 개수 및 합계와 같은 값을 계산할 수 있지만 새 노드 트리 또는 수정 된 노드 트리가 필요한 경우에는 XSLT 또는 XQuery가 필요합니다.

작은 변경 사항으로 출력물이 입력 내용과 유사 할 경우 XSLT 솔루션은 XQuery 솔루션보다 훨씬 간단합니다.

1

나는 black sowl의 솔루션을 좋아하지만 다음과 같이 약간 더 깨끗한 코드 버전을 제안한다. 다음과 같은 방법으로 세탁 기술자 :

  1. 차 이후 // 자동차를 사용할 필요가
  2. 제 1 회 return 문이
  3. 를 사용하여 단일

  4. 반복 횡단 자동차/자동차 할 필요가 불필요한입니다 루트 요소입니다 변수 이름에 & 복수의 순서

    <root> 
        { 
        let $cars := doc('cars.xml')//car 
        let $colors := distinct-values($cars/color) 
        for $color in $colors 
        return 
         <appearance color="{$color}"> 
          { 
          for $car in $cars[color = $color] 
          return 
           <car> 
            {$car/*[not(self::color or self::price)]} 
           </car> 
          } 
         </appearance> 
        } 
    </root> 
    
대 단일 항목을 나타냅니다