Xslt 如何根据纯文本文件的内容选择性地包含一个或另一个xml文件中的元素?

Xslt 如何根据纯文本文件的内容选择性地包含一个或另一个xml文件中的元素?,xslt,xslt-2.0,saxon,Xslt,Xslt 2.0,Saxon,我有两个源xml文件,需要构造一个新的xml文件,其中包含为一个或另一个文件选择的元素,这取决于它们的“名称”是否包含在纯文本文件中 xml文件a: abc1 abc2 abc3 xml文件b: xyz1 xyz2 xyz3 文本文件: name1 名字3 期望输出: abc1 xyz2虽然XSLT可以输出纯文本,但输入文档应该是XML。然而,在您的转换中可以混合使用Java。就我个人而言,我会添加一些java函数来打开文件,并以类似grep的方式处理它 这将是一个良好的开端。它的优

我有两个源xml文件,需要构造一个新的xml文件,其中包含为一个或另一个文件选择的元素,这取决于它们的“名称”是否包含在纯文本文件中

xml文件a:


abc1
abc2
abc3
xml文件b:


xyz1
xyz2
xyz3
文本文件:

name1
名字3
期望输出:


abc1

xyz2虽然XSLT可以输出纯文本,但输入文档应该是XML。然而,在您的转换中可以混合使用Java。就我个人而言,我会添加一些java函数来打开文件,并以类似grep的方式处理它

这将是一个良好的开端。它的优点是提到了一些更常见的XSLT处理引擎的操作方法


这一转变

<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vNames" select=
    "tokenize(unparsed-text('file:///c:/temp/delete/Names.txt'), '\s')"/>

    <xsl:variable name="vDoc1" select="document('file:///c:/temp/delete/FileA.xml')"/>
    <xsl:variable name="vDoc2" select="document('file:///c:/temp/delete/FileB.xml')"/>

 <xsl:template match="/">
     <t>
       <xsl:sequence select=
        "$vDoc1/*/*[@name = $vNames],
         $vDoc2/*/*[not(@name = $vNames)]
        "/>
     </t>
 </xsl:template>
</xsl:stylesheet>
<t>
    <data name="name1">
        <value>abc1</value>
    </data>
    <data name="name2">
        <value>abc2</value>
    </data>
    <data name="name3">
        <value>abc3</value>
    </data>
</t>
<t>
    <data name="name1">
        <value>xyz1</value>
    </data>
    <data name="name2">
        <value>xyz2</value>
    </data>
    <data name="name3">
        <value>xyz3</value>
    </data>
</t>
name1
name3
生成所需的正确结果:

<t>
   <data name="name1">
            <value>abc1</value>
      </data>
   <data name="name3">
            <value>abc3</value>
      </data>
   <data name="name2">
            <value>xyz2</value>
      </data>
</t>

abc1
abc3
xyz2
说明

<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vNames" select=
    "tokenize(unparsed-text('file:///c:/temp/delete/Names.txt'), '\s')"/>

    <xsl:variable name="vDoc1" select="document('file:///c:/temp/delete/FileA.xml')"/>
    <xsl:variable name="vDoc2" select="document('file:///c:/temp/delete/FileB.xml')"/>

 <xsl:template match="/">
     <t>
       <xsl:sequence select=
        "$vDoc1/*/*[@name = $vNames],
         $vDoc2/*/*[not(@name = $vNames)]
        "/>
     </t>
 </xsl:template>
</xsl:stylesheet>
<t>
    <data name="name1">
        <value>abc1</value>
    </data>
    <data name="name2">
        <value>abc2</value>
    </data>
    <data name="name3">
        <value>abc3</value>
    </data>
</t>
<t>
    <data name="name1">
        <value>xyz1</value>
    </data>
    <data name="name2">
        <value>xyz2</value>
    </data>
    <data name="name3">
        <value>xyz3</value>
    </data>
</t>
name1
name3

正确使用标准XSLT函数:(仅限2.0及以上版本)和以及标准XPath 2.0函数

我希望输入文档是xml文件“a”或xml文件“b”?当然,这很好。可以使用document()函数包含后续XML文件。这个线程有一些有用的信息。对于XSLT2.0来说不是这样。使用标准的
unparsed-text()
函数可以读取任何文本文件。没错,您是关于XSLT 2.0的。但是,我要指出,除了Saxon之外,许多流行的处理引擎(例如libxslt)只支持XSLT1.0。谢谢。Saxon给出了这个错误:“NotSpecified:(无源文件名:String)[],RemoteException”。此外,我的xml文件还有其他元素,我希望在输出中复制这些元素(它们在文件“a”和文件“b”中是相同的),这种方法在这种情况下仍然有效吗?(如果这是我应该在问题中提出的重要信息,那么很抱歉)@JackDouglas,如果您只是使用给定的文件路径和文件名创建文件,并使用Saxon 9(或任何其他兼容的XSLT 2.0处理器)运行此转换,那么您必须得到与我得到的结果相同的结果(使用Saxon 9.1.07),并将结果复制并粘贴到此答案中。对于问题中没有规定的新需求,我强烈建议您提出一个新的、单独的问题,并在那里完整地描述它们。以目前的形式,你的问题已经完全得到了回答。简单的回答是,FileB中任何未引用的元素都会被复制到输出中。我已经这样做了(除了更改路径名),并且我得到了相同的错误是否可能是因为我使用的是.NET变量,而您使用的是Java变量?我不知道。我相信这对你是有效的,但是我很高兴,因为我已经能够适应你的答案,以得到我想要的。万分感谢@杰克道格拉斯,不客气。除非我能看到你的代码,否则我不能说是什么错误。很高兴您能够根据自己的需要调整此解决方案。