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

时间:2012-12-17 18:48:47

标签: xslt xslt-2.0 saxon

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

xml文件a:

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

xml文件b:

<data name="name1">
  <value>xyz1</value>
</data>
<data name="name2">
  <value>xyz2</value>
</data>
<data name="name3">
  <value>xyz3</value>
</data>

文本文件:

name1
name3

期望的输出:

<data name="name1">
  <value>abc1</value>
</data>
<data name="name2">
  <value>xyz2</value>        <---- note this element is from file 'b'
</data>
<data name="name3">
  <value>abc3</value>
</data>

因此,名称为“name1”和“name3”的元素来自“xml文件a”,因为它们列在文本文件中,但“name2”来自“xml文件b”,因为它不是。

实际名称不是'name1'等,而是任意字符串标识符,但它们在文件中是唯一的。

是否可以使用XSLT执行此操作?

2 个答案:

答案 0 :(得分:3)

此转化

<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>

应用于任何XML文档(未使用)并具有这两个文件

<强> C:/temp/delete/FileA.xml

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

<强> C:/temp/delete/FileB.xml

<t>
    <data name="name1">
        <value>xyz1</value>
    </data>
    <data name="name2">
        <value>xyz2</value>
    </data>
    <data name="name3">
        <value>xyz3</value>
    </data>
</t>

<强> C:/temp/delete/Names.txt

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>

<强>解释

正确使用标准XSLT功能: unparsed-text() (仅限2.0及以上)和 document() 以及标准XPath 2.0功能 tokenize()

答案 1 :(得分:-1)

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

这个将军tutorial on adding Java functions to XSLT stylesheets将是一个良好的开端。它的优点是可以为一些更常见的XSLT处理引擎提及操作方法。

Here's a related discussion on SO