2011-10-06 3 views
4

내가 (제거 이상의 노드 및 세부 사항)이 유사한 XML 파일이 노드 :필터 XML은

<?xml version="1.0" encoding="utf-8"?> 
<Message xmlns="http://www.theia.org.uk/ILR/2011-12/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<Header> 
    <CollectionDetails> 
     <Collection>ILR</Collection> 
     <Year>1112</Year> 
     <FilePreparationDate>2011-10-06</FilePreparationDate> 
    </CollectionDetails> 
    <Source> 
     <ProtectiveMarking>PROTECT-PRIVATE</ProtectiveMarking>   
    </Source> 
</Header> 
<SourceFiles> 
    <SourceFile> 
     <SourceFileName>A10004705001112004401.ER</SourceFileName> 
     <FilePreparationDate>2011-10-05</FilePreparationDate> 
    </SourceFile> 
</SourceFiles> 
<LearningProvider> 
    <UKPRN>10004705</UKPRN> 
    <UPIN>107949</UPIN> 
</LearningProvider> 
<Learner> 
    <ULN>4682272097</ULN> 
    <GivenNames>Peter</GivenNames> 
    <LearningDelivery> 
     <LearnAimRef>60000776</LearnAimRef>   
    </LearningDelivery>  
    <LearningDelivery> 
     <LearnAimRef>ZPROG001</LearnAimRef>   
    </LearningDelivery> 
</Learner> 
<Learner> 
    <ULN>3072094321</ULN>  
    <GivenNames>Thomas</GivenNames>  
    <LearningDelivery> 
     <LearnAimRef>10055320</LearnAimRef>   
    </LearningDelivery> 
    <LearningDelivery> 
     <LearnAimRef>10002856</LearnAimRef>   
    </LearningDelivery> 
    <LearningDelivery> 
     <LearnAimRef>1000287X</LearnAimRef>   
    </LearningDelivery> 
</Learner> 
</Message> 

내가 있도록이를 필터링해야 아이의 LearningDelivery LearnAimRef가있는 경우에만 학습자 기록 나는이 작업을 수행 할 수있는 올바른 방법을 이렇게하고 생각하는 방법으로 보았다

<?xml version="1.0" encoding="utf-8"?> 
<Message xmlns="http://www.theia.org.uk/ILR/2011-12/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<Header> 
    <CollectionDetails> 
     <Collection>ILR</Collection> 
     <Year>1112</Year> 
     <FilePreparationDate>2011-10-06</FilePreparationDate> 
    </CollectionDetails> 
    <Source> 
     <ProtectiveMarking>PROTECT-PRIVATE</ProtectiveMarking>   
    </Source> 
</Header> 
<SourceFiles> 
    <SourceFile> 
     <SourceFileName>A10004705001112004401.ER</SourceFileName> 
     <FilePreparationDate>2011-10-05</FilePreparationDate> 
    </SourceFile> 
</SourceFiles> 
<LearningProvider> 
    <UKPRN>10004705</UKPRN> 
    <UPIN>107949</UPIN> 
</LearningProvider> 
<Learner> 
    <ULN>4682272097</ULN> 
    <GivenNames>Peter</GivenNames> 
    <LearningDelivery> 
     <LearnAimRef>60000776</LearnAimRef>   
    </LearningDelivery>  
    <LearningDelivery> 
     <LearnAimRef>ZPROG001</LearnAimRef>   
    </LearningDelivery> 
</Learner> 
</Message> 

프로세스에 XSL 변환을 사용하는 것입니다 ZPROG001 그래서이 경우 출력은 첫째 학습자하지만 두 번째없는 것이다 표시됩니다 xml을 만들고 새 파일에 필요한만큼 출력합니다 (C#에서 수행). 두 시간 후에 XSLT 문법 주위에 내 머리를 감싸려고하면 나는 여전히 붙어있어 내가 원하는 출력을 얻을 수 없다. 어떤 도움을 많이 주셨습니다.

답변

4

특정 부분을 수정하는 XML 소스 문서의 대부분을 복사하려면, 당신은 항등 변환으로 시작하는 것이 좋습니다. 이것은 단지 모든 것을 복사합니다. 그런 다음 복사하지 않을 <Learner> 요소의 정체성 서식을 재정의 할 템플릿을 추가

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:theia="http://www.theia.org.uk/ILR/2011-12/1"> 
    <!-- identity template --> 
    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
    <!-- override the above template for certain Learner elements; output nothing. --> 
    <xsl:template match="theia:Learner[ 
    not(theia:LearningDelivery/theia:LearnAimRef = 'ZPROG001')]"> 
    </xsl:template> 
</xsl:stylesheet> 

(@andyb에서 차입 네임 스페이스 접두사를).

+1

+1 좋은 답변입니다. –

+0

훌륭한 답변이 제가 원했던 것과 똑같습니다. XSLT가 조금 더 이해 되었으면 좋겠다. – PeteT

1

그냥 다음 노드 집합을 필터링하는 술어 표현합니다 ([] 사이의 비트)를 사용하여 특정 값 (이 경우 LearnAimRef에서) 자손이있는 모든 <Learner> 요소를 원하는 경우 .

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:theia="http://www.theia.org.uk/ILR/2011-12/1"> 
<xsl:template match="/theia:Message"> 
    <xsl:copy-of select="theia:Learner[theia:LearningDelivery/theia:LearnAimRef='ZPROG001']"/> 
</xsl:template> 
</xsl:stylesheet> 

는 그래서 copy-ofdefault namespace의를 가지고 ZPROG001

귀하의 XML 문서에 같은 값을 가지고 LearnAimRef라는 아이가 LearningDelivery라는 아이가 그 모든 학습자 노드를 복사 할 읽는다 "http://www.theia.org.uk/ILR/2011-12/1"그래서 XPath가 올바르게 노드를 선택하려면 동일한 네임 스페이스 선언을 사용해야하므로 위의 XSLT에서 네임 스페이스를 별칭에 할당하고이를 XPath에 사용했습니다. 당신이 출력 트리에 XML 소스 복사의 다른 부분을 원하는 경우에

, 당신은 그러나 이미 답을 가지고, 이것은 C#으로 변환을 적용하는 대답하지 예를 <xsl:copy-of select="theia:LearningProvider"/>

에 대한 추가 규칙을 추가 할 수 있습니다 - How to apply an XSLT Stylesheet in C#

희망이 도움이 :)

+0

특히 네임 스페이스 문제로 원하는 학습자 요소를 선택하는 방법을 보여주는 것이 좋습니다. 그러나 OP는 자신이 원하는 출력에서 ​​그가 대부분의 문서를 복사하기를 원했음을 보여주었습니다. 올바른 내용이없는 ''요소 만 생략됩니다. – LarsH

+0

그래, 나는 대답에서 더 많은 노드를 복사하고 XSLT가 완전하지 않다는 언급을했다. 더 깨끗하고 완전한 답변을 +1하십시오. – andyb

+0

답변 주셔서 감사합니다. 문제가있는 실제 XSLT 파일 인 C# 측을 처리했습니다. – PeteT