根据子节点过滤XML

Pet*_*teT 4 xml xslt

我有一个类似于此的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>
Run Code Online (Sandbox Code Playgroud)

我需要对此进行过滤,以便只有具有ZPROG001的子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>
Run Code Online (Sandbox Code Playgroud)

我已经研究了如何做到这一点,并相信正确的方法是使用XSL转换来处理xml并根据需要输出到新文件(在c#中执行此操作).几个小时后,我试图围绕XSLT语法包围我仍然卡住,无法得到我想要的输出.任何帮助非常感谢.

Lar*_*rsH 5

要复制大多数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>
Run Code Online (Sandbox Code Playgroud)

(从@andyb借用名称空间前缀).