我有一个类似于此的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>
我需要对此进行过滤,以便只有具有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>
我已经研究过如何做到这一点并且相信正确的方法是使用XSL转换来处理xml并根据需要输出到新文件(在c#中执行此操作)。几个小时后,我试图围绕XSLT语法包围我仍然卡住,无法得到我想要的输出。任何帮助非常感谢。
答案 0 :(得分: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>
(从@andyb借用名称空间前缀)。
答案 1 :(得分:1)
如果您只想要具有特定值的所有具有后代的<Learner>
元素(在本例中为 LearnAimRef ),则可以使用谓词表达式({{之间的位) 1}}和[
)来过滤节点集。
]
所以<?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>
读取为复制所有学习者节点,其中有一个名为LearningDelivery的子节点,其中有一个名为LearnAimRef的子节点,其值等于ZPROG001
你的XML文档有一个default namespace“http://www.theia.org.uk/ILR/2011-12/1”所以为了让XPath正确选择一个节点,它必须使用相同的命名空间声明,所以在上面的XSLT中,我有将您的命名空间分配给别名并在XPath中使用它。
如果您希望XML源的其他部分复制到输出树,则可以添加其他规则,例如copy-of
这不是在C#中应用转换的答案,但已经回答过了 - How to apply an XSLT Stylesheet in C#
希望这会有所帮助:)