2012-04-21 64 views
1

这是我的xml:如何在循环期间更新或追加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> 

如果任何样品/ DO的类型,名称和参考文献与任何文档/文件类型,名称和ref的匹配。使用文档/文本更新样本/ DO /文本。否则(如果任何样品/类型,名称,参考文献与文档/文档类型,名称,参考文献不匹配),则应附加整个文档/文档。

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

+0

你使用纯xpath还是其他语言 – 2012-04-21 05:58:49

+0

需要使用xpath(1.0或2.0)实现它 – cbx 2012-04-21 06:11:04

+0

@bose:这是什么意思:“否则(如果任何样本/ Do的类型,name,ref与Docs/Document类型,name,ref不匹配),那么应附加从Docs/Document开始的整个Document。“ *应该附加哪个*文档/文档?请解释。 – 2012-04-21 16:33:53

回答

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/

1

如果使用XSLT来复制和转换文档,你可以利用两个XSL:关键** s到查找**文件元素和SO元素。在这种情况下,你需要重点

<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))]"> 

匹配的文档元素(如果所有SO元素被保证SO元素有一个匹配的**文档元素,这可以简化为<xsl:template match="DO" >

在此模板中那么您可以简单地将代码添加到此模板中,以便从密钥中复制元素中的文本元素。

要匹配文档元素没有相应的SO元素,你可以这样做:

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

请注意我排除在输出文档节点,但是从XSLT如果只是删除相关行你想保留它们。

+0

发誓:-) 非常感谢。这正是我正在寻找的。 – cbx 2012-04-21 13:33:13