过滤XML节点
我有类似这样的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只有学习者记录ZPROG001将显示所以在这种情况下,输出将是第一个学生,但不是第二:
<?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转换过程xml和根据需要输出到一个新文件(在c#中执行此操作)。经过几个小时试图围绕XSLT语法包装我的头,我仍然卡住,无法获得我想要的输出。任何帮助非常感谢。
要复制大多数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前缀)。
如果你只是希望所有具有后代(在这种情况下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-of
全文复制所有学习者的节点,有一个叫LearningDelivery孩子其中有一个叫LearnAimRef的孩子,有等于ZPROG001
你的XML文档中的值具有default namespace的“http://www.theia.org.uk/ILR/2011-12/1”,所以为了让XPath正确选择一个节点,它必须使用相同的名称空间声明,因此在上面的XSLT中,我已将您的名称空间分配给别名,并在XPath中使用它。
如果你想在XML源复制到输出树的其他部分,你可以添加更多的规则,例如<xsl:copy-of select="theia:LearningProvider"/>
这不是在C#应用转换的答案,但是这已经被回答 - How to apply an XSLT Stylesheet in C#
希望这有助于:)
+1为一个很好的答案。 –
优秀的答案,这正是我想要的。我希望我能更多地理解XSLT,但它对我来说只是一次。 – PeteT