1

这是我的xml:

<rootNode>
    <sample>
        <DO type="TD" name="ABC" ref="1">
            <text>text</text>
        </DO>
        <DO type="CI" name="DEF" ref="2">
            <text></text>
        </DO>
        <DO type="PL" name="GHI" ref="3">
            <text>text</text>
        </DO>
        <DO type="AB" name="JKL" ref="4">
            <text>text</text>
        </DO>   
    </sample>
    <Docs>
        <Document>
            <type>TD</type>
            <name>ABC</name>
            <ref>1</ref>
            <text>sample text</text>
        </Document>
        <Document>
            <type>CI</type>
            <name>DEF</name>
            <ref>2</ref>
            <text>sample text</text>
        </Document>
        <Document>
            <type>PL</type>
            <name>GHI</name>
            <ref>3</ref>
            <text>sample text</text>
        </Document>
        <Document>
            <type>AB</type>
            <name>JKL</name>
            <ref>4</ref>
            <text>sample text</text>
        </Document>
        <Document>
            <type>CD</type>
            <name>JKL</name>
            <ref>5</ref>
            <text>sample text</text>
        </Document>
    </Docs>
</rootNode>

如果任何 sample/DO 的类型、名称和引用与任何 Docs/文档类型、名称和引用匹配。用 Document/text 更新 sample/DO/text。否则(如果任何 sample/Do 的 type、name、ref 与 Docs/Document type、name、ref 不匹配),则应附加 Docs/Document 中的整个 Document。

注意:样品/DO 的顺序不应改变。我的意思是,如果任何文件有任何匹配项,都应该更新。否则应追加新的。

4

2 回答 2

1

如果您使用 XSLT 来复制和转换文档,您可以使用两个xsl:key**s 来查找 **Document元素和SO元素。在这种情况下,您需要一个复合键

<xsl:key name="docs" match="Document" use="concat(type, '|', name, '|', ref)"/>
<xsl:key name="samples" match="DO" use="concat(@type, '|', @name, '|', @ref)"/>

您可以首先匹配具有匹配Document元素的SO元素,如下所示

<xsl:template match="DO[key('docs', concat(@type, '|', @name, '|', @ref))]">

(如果保证所有SO元素都具有匹配的 **Document 元素,则可以将其简化为<xsl:template match="DO" >

在此模板中,您可以简单地向此模板添加代码,以从键中的Document元素复制文本元素。

要匹配没有相应SO元素的Document元素,您可以这样做:

<xsl:apply-templates 
   select="/rootNode/Docs/Document[not(key('samples', concat(type, '|', name, '|', ref)))]"
   mode="Document"/>

对于匹配的模板,您可以将其转换为SO元素。

这是完整的 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="docs" match="Document" use="concat(type, '|', name, '|', ref)"/>
   <xsl:key name="samples" match="DO" use="concat(@type, '|', @name, '|', @ref)"/>


   <xsl:template match="DO[key('docs', concat(@type, '|', @name, '|', @ref))]">
      <xsl:copy>
         <xsl:apply-templates select="@*"/>
            <xsl:copy-of select="key('docs', concat(@type, '|', @name, '|', @ref))/text"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="sample">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
         <xsl:apply-templates select="/rootNode/Docs/Document[not(key('samples', concat(type, '|', name, '|', ref)))]" mode="Document"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="Document" mode="Document">
         <DO type="{type}" name="{name}" ref="{ref}">
            <xsl:copy-of select="text" />
         </DO>
   </xsl:template>

   <xsl:template match="Docs" />

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

以下是输出

<rootNode>
   <sample>
      <DO type="TD" name="ABC" ref="1">
         <text>sample text</text>
      </DO>
      <DO type="CI" name="DEF" ref="2">
         <text>sample text</text>
      </DO>
      <DO type="PL" name="GHI" ref="3">
         <text>sample text</text>
      </DO>
      <DO type="AB" name="JKL" ref="4">
         <text>sample text</text>
      </DO>
      <DO type="CD" name="JKL" ref="5">
         <text>sample text</text>
      </DO>
   </sample>
</rootNode>

请注意,我从输出中排除了Docs节点,但如果您想保留它们,只需从 XSLT 中删除相关行。

于 2012-04-21T09:21:31.210 回答
0

据我所知,您不能仅通过使用纯 xpath 来更新文档,xpath 的想法主要用于根据某些比较从文档中选择特定节点。实现这一点的唯一好方法是使用另一种可以使用 xpath 和更新元素的语言,比如 php Simplexml。阅读不同的来源,许多人会推荐不同的建议,但它主要通过 xquery 解决,这里有几个链接。

http://www.w3.org/XML/Query/

http://www.w3.org/TR/xquery-update-10-use-cases/

http://www.w3.org/TR/xquery-update-10/

于 2012-04-21T06:25:23.423 回答