2

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

xml文件一:

<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 做到这一点?

4

2 回答 2

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

于 2012-12-17T20:46:01.323 回答
-1

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

这个关于将 Java 函数添​​加到 XSLT 样式表的一般教程将是一个好的开始。它的优点是提及一些更常见的 XSLT 处理引擎的操作方法。

这是关于SO的相关讨论

于 2012-12-17T19:01:24.290 回答