2013-08-23 1 views
0

와 노드를 교체하십시오. XQuery를 사용하여 동일한 구조의 새 문서를 비교하고 싶습니다. 새 요소와 원본 요소에 하위 요소가 있으면 교체해야합니다. 새 요소에 하위 요소가 있지만 이전 요소가 아닌 하위 요소는 INVT_DATA에 추가되어야합니다.XQuery는이 같은 구조화 된 문서를 두 문서를 비교하고 같은 이름

이 XQuery를, 내 생각, 작동하지만 그것은 언제나 대신에 노드를 추가 할 것 같습니다

declare namespace invtdata="http://www.mrbook.com/InventoryData"; 

copy $oldInvtData := $oldXml 

modify 
( 
    for $mpf in $newXml/invtdata:INVT_DATA/* 
    let $oldMpf := $oldInvtData/invtdata:INVT_DATA/*[name()=name($mpf)] 
    return if(exists($oldMpf)) then 
    replace node $oldMpf with $mpf 
    else insert node $mpf into $oldInvtData 
) 
return $oldInvtData 

내가 다른 비슷한 문제를 검색하고 this을 찾았지만, 그 무엇에 대한 과잉 꽤입니다 나하고 싶어. 어떤 제안? 도움이된다면 Oracle XML DB 버전 11.2.0.3에서 XmlQuery를 사용하고 있습니다.

+1

'name()'은 종종 이와 같은 문제를 일으 킵니다. 예상 한 네임 스페이스 접두어를 반환하지 않는 경우가 많습니다. 나는 그것을'localname()'으로 바꾸고 그것이 작동 하는지를 보려고한다. 네임 스페이스가 관련된 경우 다른 조건 자 (또는 절)를 추가하여 비교할 수 있습니다. –

답변

0

이것은 올바른 코드로 밝혀졌습니다. 단지 하나의 작은 조정입니다.

declare namespace invtdata="http://www.mrbook.com/InventoryData"; 

declare variable $oldXml := doc('.../Brad1.xml'); 
declare variable $newXml := doc('.../Brad2.xml'); 

copy $oldInvtData := $oldXml 

modify 
( 
    for $mpf in $newXml/invtdata:INVT_DATA/* 
    let $oldMpf := $oldInvtData/invtdata:INVT_DATA/* 
       [local-name() = local-name($mpf) 
        and namespace-uri() = namespace-uri($mpf)] 
    return if(exists($oldMpf)) then 
    replace node $oldMpf with $mpf 
    else insert node $mpf into $oldInvtData/invtdata:INVT_DATA 
) 
return $oldInvtData 

감사합니다.

1

name()은 XML에 나타나는 이름을 반환하기 때문에 오류가 발생하기 쉽습니다. 두 입력이 네임 스페이스 이름에 다른 접두사를 바인딩하고 name() 성공하지 못한다. 술어를

[local-name() = local-name($mpf) 
and 
namespace-uri() = namespace-uri($mpf)] 

으로 변경하면 코드가 더 잘 작동합니다.


부록 :

<INVT_DATA xmlns="http://www.mrbook.com/InventoryData"> 
    <AUTHOR>old author</AUTHOR> 
    <TITLE>old title</TITLE> 
    <PUBLISHER>old publisher</PUBLISHER> 
</INVT_DATA> 

다음과 같은 내용으로 XML 문서 Brad2.xml : 다음과 같은 내용으로 XML 문서 Brad1.xml 주어집니다

<id:INVT_DATA xmlns:id="http://www.mrbook.com/InventoryData"> 
    <id:AUTHOR>new author</id:AUTHOR> 
    <id:PUBLISHER>new publisher</id:PUBLISHER> 
</id:INVT_DATA> 

코드 :

declare namespace invtdata="http://www.mrbook.com/InventoryData"; 

declare variable $oldXml := doc('.../Brad1.xml'); 
declare variable $newXml := doc('.../Brad2.xml'); 

copy $oldInvtData := $oldXml 

modify 
( 
    for $mpf in $newXml/invtdata:INVT_DATA/* 
    let $oldMpf := $oldInvtData/invtdata:INVT_DATA/* 
       [local-name() = local-name($mpf) 
        and namespace-uri() = namespace-uri($mpf)] 
    return if(exists($oldMpf)) then 
    replace node $oldMpf with $mpf 
    else insert node $mpf into $oldInvtData 
) 
return $oldInvtData 

가 평가 : 전혀 대체 어떤 노드가 표시되지 않는 경우

<INVT_DATA xmlns="http://www.mrbook.com/InventoryData" 
      xmlns:id="http://www.mrbook.com/InventoryData"> 
    <id:AUTHOR>new author</id:AUTHOR> 
    <TITLE>old title</TITLE> 
    <id:PUBLISHER>new publisher</id:PUBLISHER> 
</INVT_DATA> 

가 하나의 원인이 XPath 식에 오류가 (당신은 그들이 모두 올바른지 확인입니까? 오타가 없습니까?); 또 다른 것은 $ oldXml 또는 $ newXml을 의도 한대로 바인드하지 못하는 것입니다.

+0

제안 해 주셔서 감사합니다! 나는 그것을 밖으로 시도 할 것이다! – Brad

+0

불행히도, local-name을 사용하면 namespace-uri 조건이 없더라도 노드를 전혀 대체하지 않습니다. '$ newXml // invtdata : INVT_DATA'를 시도해 보았습니다. 올바른 노드를 잡았지만 성공하지 못했습니다. – Brad

+0

우리는 한걸음 더 나아가고 있습니다. 이 내용을 복사하여 붙여 넣으면 업데이트가 수행되지만 삽입은 수행되지 않습니다. – Brad

관련 문제