2

我对 XSLT 完全陌生,所以请多多包涵。

我有两个 xml 文件,我试图使用 XSLT 将它们连接在一起。我想组合这些文件,以便第二个文件中指定的任何值都覆盖第一个文件。例如

第一文件.xml

<person>
  <person-name>Sandy</person-name>
  <person-age>21</person-age>
</person>

<person>
  <person-name>Bob</person-name>
  <person-age>15</person-age>
</person>

覆盖.xml

<person>
  <person-name>Bob</person-name>
  <person-age>21</person-age>
</person>

结果:

<person>
  <person-name>Sandy</person-name>
  <person-age>21</person-age>
</person>
<person>
  <person-name>Bob</person-name>
  <person-age>21</person-age>
</person>

我用于连接 2 个文件的模板如下:

  <xsl:template match="/">
     <!-- MainFile -->
     <xsl:copy-of select="/*"/>

      <!-- Overrides-->
      <xsl:copy-of select="document($overrideFile)/*"/>
  </xsl:template>

我试图设置一个 for-each 循环,以便在复制 firstFile.xml 中的每个人之前检查 override.xml 中是否有相应的节点,但不成功。

任何提示将非常感谢

4

1 回答 1

3

这种转变

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

 <xsl:param name="pDoc2Url" select="'file:///c:/temp/delete/override.xml'"/>
 <xsl:variable name="vDoc2" select="document($pDoc2Url)"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <t>
    <xsl:apply-templates
       select="person[not(person-name = $vDoc2/*/person/person-name)]"/>
    <xsl:apply-templates select="$vDoc2/*/person"/>
  </t>
 </xsl:template>
</xsl:stylesheet>

当应用于第一个提供的 XML 文档时(包装到单个顶部元素中 - 将成为格式良好的 XML 文档):

<t>
    <person>
        <person-name>Sandy</person-name>
        <person-age>21</person-age>
    </person>
    <person>
        <person-name>Bob</person-name>
        <person-age>15</person-age>
    </person>
</t>

并作为参数传递第二个文档(再次包装到顶部元素)所在的文件名 - 这是更正后的第二个文档

c:/temp/delete/override.xml

<t>
    <person>
        <person-name>Bob</person-name>
        <person-age>21</person-age>
    </person>
</t>

产生想要的正确结果:

<t>
   <person>
      <person-name>Sandy</person-name>
      <person-age>21</person-age>
   </person>
   <person>
      <person-name>Bob</person-name>
      <person-age>21</person-age>
   </person>
</t>

二、一个更短但不太灵活的解决方案——没有身份规则,也没有xsl:apply-templates

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

 <xsl:param name="pDoc2Url" select="'file:///c:/temp/delete/override.xml'"/>
 <xsl:variable name="vDoc2" select="document($pDoc2Url)"/>

 <xsl:template match="/*">
  <t>
    <xsl:copy-of
       select="person[not(person-name = $vDoc2/*/person/person-name)]"/>
    <xsl:copy-of select="$vDoc2/*/person"/>
  </t>
 </xsl:template>
</xsl:stylesheet>
于 2012-12-13T03:16:15.693 回答