2010-05-04 3 views
1

병합해야하는 두 개의 문서가 있습니다. 다른 예제에서 찾을 수없는 것으로 보입니다. 즉, 한 레벨의 노드 속성뿐만 아니라 노드 레벨 값을 얻기 위해 그 아래의 노드 레벨 속성 값에도 일치해야합니다.비슷한 XML 파일을 XSL로 병합하는 데 문제가 있습니다.

내가이 샘플 걸릴하려고 해요 :

<?xml version="1.0" encoding="UTF-8" ?> 
<marc:collection xmlns:marc="http://www.loc.gov/MARC21/slim" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <marc:record> 
    <marc:datafield tag="035" ind1=" " ind2=" "> 
     <marc:subfield code="a">12345</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="041" ind1=" " ind2=" "> 
     <marc:subfield code="a">eng</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="650" ind1=" " ind2="4"> 
     <marc:subfield code="a">Art</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="949" ind1=" " ind2=" "> 
     <marc:subfield code="i">Review of conference proceedings</marc:subfield> 
    </marc:datafield> 
    </marc:record> 
    <marc:record> 
    <marc:datafield tag="035" ind1=" " ind2=" "> 
     <marc:subfield code="a">54321</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="041" ind1=" " ind2=" "> 
     <marc:subfield code="a">eng</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="650" ind1=" " ind2="4"> 
     <marc:subfield code="a">Byzantine</marc:subfield> 
    </marc:datafield> 
    </marc:record> 
</marc:collection> 

그리고 "데이터 필드" '035', '서브 필드 "의 값이'A는, 예를 들어 일치 할 때를 "12345"

<marc:collection xmlns:marc="http://www.loc.gov/MARC21/slim" 
xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
    <marc:record> 
    <marc:datafield ind2=" " ind1=" " tag="035"> 
     <marc:subfield code="a">12345</marc:subfield> 
    </marc:datafield> 
    <marc:datafield ind2="4" ind1=" " tag="650"> 
     <marc:subfield code="a">General works</marc:subfield> 
     <marc:subfield code="x">Historians and critics</marc:subfield> 
     <marc:subfield code="x">Smith, John, 1834-1917</marc:subfield> 
    </marc:datafield> 
    <marc:datafield ind2="4" ind1=" " tag="650"> 
     <marc:subfield code="a">Généralités</marc:subfield> 
     <marc:subfield code="x">Historiens et critiques d'art</marc:subfield> 
     <marc:subfield code="x">Dietrichson, Lorentz, 1834-1917</marc:subfield> 
    </marc:datafield> 
    <marc:datafield ind2=" " ind1=" " tag="654"> 
     <marc:subfield code="a">General works</marc:subfield> 
    </marc:datafield> 
    <marc:datafield ind2=" " ind1=" " tag="654"> 
     <marc:subfield code="a">Généralités</marc:subfield> 
     <marc:subfield code="b">Historiens et critiques d'art</marc:subfield> 
     <marc:subfield code="b">Smith, John, 1834-1917</marc:subfield> 
    </marc:datafield> 
    </marc:record>  
    <marc:record> 
    <marc:datafield ind2=" " ind1=" " tag="035"> 
     <marc:subfield code="a">54321</marc:subfield> 
    </marc:datafield> 
    <marc:datafield ind2="4" ind1=" " tag="650"> 
     <marc:subfield code="a">General works</marc:subfield> 
     <marc:subfield code="x">Historians and critics</marc:subfield> 
     <marc:subfield code="x">Lange, Julius Henrik, 1838-1896</marc:subfield> 
    </marc:datafield> 
    </marc:record> 
</marc:collection> 

결과는 같아야합니다

<?xml version="1.0" encoding="UTF-8" ?> 
<marc:collection xmlns:marc="http://www.loc.gov/MARC21/slim" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <marc:record> 
    <marc:datafield tag="035" ind1=" " ind2=" "> 
     <marc:subfield code="a">12345</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="041" ind1=" " ind2=" "> 
     <marc:subfield code="a">eng</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="650" ind1=" " ind2="4"> 
     <marc:subfield code="a">Art</marc:subfield> 
    </marc:datafield> 
    <marc:datafield ind2="4" ind1=" " tag="650"> 
     <marc:subfield code="a">General works</marc:subfield> 
     <marc:subfield code="x">Historians and critics</marc:subfield> 
     <marc:subfield code="x">Smith, John, 1834-1917</marc:subfield> 
    </marc:datafield> 
    <marc:datafield ind2="4" ind1=" " tag="650"> 
     <marc:subfield code="a">Généralités</marc:subfield> 
     <marc:subfield code="x">Historiens et critiques d'art</marc:subfield> 
     <marc:subfield code="x">Dietrichson, Lorentz, 1834-1917</marc:subfield> 
    </marc:datafield> 
    <marc:datafield ind2=" " ind1=" " tag="654"> 
     <marc:subfield code="a">General works</marc:subfield> 
    </marc:datafield> 
    <marc:datafield ind2=" " ind1=" " tag="654"> 
     <marc:subfield code="a">Généralités</marc:subfield> 
     <marc:subfield code="b">Historiens et critiques d'art</marc:subfield> 
     <marc:subfield code="b">Smith, John, 1834-1917</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="949" ind1=" " ind2=" "> 
     <marc:subfield code="i">Review of conference proceedings</marc:subfield> 
    </marc:datafield> 
    </marc:record> 
    <marc:record> 
    <marc:datafield tag="035" ind1=" " ind2=" "> 
     <marc:subfield code="a">54321</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="041" ind1=" " ind2=" "> 
     <marc:subfield code="a">eng</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="650" ind1=" " ind2="4"> 
     <marc:subfield code="a">Byzantine</marc:subfield> 
    </marc:datafield> 
    <marc:datafield ind2="4" ind1=" " tag="650"> 
     <marc:subfield code="a">General works</marc:subfield> 
     <marc:subfield code="x">Historians and critics</marc:subfield> 
     <marc:subfield code="x">Lange, Julius Henrik, 1838-1896</marc:subfield> 
    </marc:datafield> 
    </marc:record> 
</marc:collection> 

내가 조회를했던 내가 찾은 예를 사용하여 시도했지만, 그들 중 누구도 일 것 같았다. 모든 결과가 재앙 이었기 때문에 XSL을 포함하지 않았습니다. 나는 그것을 계속보고, 그것이 간단해야하지만, 나는 단지 괜찮은 결과를 얻지 못하고있다. 어떤 도움이나 조언을 주시면 감사하겠습니다.

감사합니다.

답변

0

나는 당신에게 대답 할 것 같아요. 가장 우아하지는 않지만 작동합니다. 기본적으로 병합하려는 XML 파일 중 하나에 대해 스타일 시트를 실행 한 다음 문서 함수를 사용하여 다른 XML 파일에 액세스합니다. 첫 번째 XML 파일의 각 레코드를 반복하고 일치하는 지점을 찾습니다. 그런 다음 두 번째 문서를 통해 반복과 일치하는 레코드를 찾을 수에 해당하는 노드를 당깁니다.

<?xml version="1.0" encoding="UTF-8"?> 

<xsl:variable name="doc2" select="document('FourBabyMarcs.xml')"/> 

<xsl:template match="/"> 
    <marc:collection> 
     <xsl:for-each select="marc:collection/marc:record"> 
      <marc:record> 

       <xsl:for-each select="marc:leader"> 
        <xsl:copy-of select="."/> 
       </xsl:for-each> 

       <xsl:for-each select="marc:controlfield"> 
        <xsl:copy-of select="."/> 
       </xsl:for-each> 

       <xsl:for-each select="marc:datafield"> 
        <xsl:copy-of select="."/> 
       </xsl:for-each> 

       <xsl:variable name="ID"> 
        <xsl:value-of select="marc:datafield[@tag='035']/marc:subfield[@code='a']"/> 
       </xsl:variable> 

       <xsl:for-each select="$doc2/*/marc:record"> 
         <xsl:if test="marc:datafield[@tag='035']/marc:subfield[@code='a']=$ID"> 
          <xsl:for-each select="marc:datafield"> 
           <xsl:if test="@tag='650'"> 
            <xsl:copy-of select="."/> 
           </xsl:if> 
           <xsl:if test="@tag='654'"> 
            <xsl:copy-of select="."/> 
           </xsl:if> 
          </xsl:for-each> 
         </xsl:if> 
       </xsl:for-each> 
      </marc:record> 
     </xsl:for-each> 
    </marc:collection> 
</xsl:template> 

0

다음 솔루션은 병합 된 문서의 효율적인 검색을하기 위해 키를 사용 . 일치하는 datafield을 제외한 모든 datafield 요소를 복사해야하며 각 record에 대해 하나만 일치하는 datafield이 있다고 가정합니다. 병합해야 할 문서의 URL이 매개 변수로 전달됩니다.

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:marc="http://www.loc.gov/MARC21/slim"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:param name="mergeFile"/> 
    <xsl:variable name="mergeDoc" select="document($mergeFile)"/> 

    <xsl:key name="datafield" match="marc:datafield" 
     use="concat(@tag, '|', marc:subfield[@code='a'])"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:template> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="marc:record"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
      <xsl:apply-templates select="marc:datafield" mode="merge"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="marc:datafield" mode="merge"> 
     <xsl:variable name="datafieldKey" 
         select="concat(@tag, '|', marc:subfield[@code='a'])"/> 
     <!-- Make the other document the context node with for-each, so that 
      key lookups will consult that document instead of the source 
      document. --> 
     <xsl:for-each select="$mergeDoc"> 
      <xsl:for-each select="key('datafield', $datafieldKey)"> 
       <xsl:copy-of select="preceding-sibling::*"/> 
       <xsl:copy-of select="following-sibling::*"/> 
      </xsl:for-each> 
     </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 
관련 문제