【问题标题】:Finding the differences in xml nodes查找 xml 节点的差异
【发布时间】:2012-09-20 13:09:49
【问题描述】:

XML/XSLT 新手在这里。 我有一些需要比较的数据集。输出需要是不在当前名册中的名册的先前成员的列表。该节点包含两组元素,我需要循环浏览并将缺少的成员放入 csv 文件中。 在下面的示例中,Kerry Smith 被列为“Previous_Members”而不是“Member”,因此她需要在输出中列出。

同样的结构会出现在多个团队中。不同的团队可以有不同的#。 (Smith 队可能有 4 名成员,Jones 队可能有 7 名成员,Jackson 队可能有 10 名成员,等等。)所以解决方案需要能够处理可变数量的元素。

这对我来说是一个很大的经验,所以任何指导将不胜感激。

<?xml version="1.0" encoding="UTF-8"?>
<am:Team>
<am:First_Day>08/24/2012</am:First_Day>
<am:_Date>08/23/2012</am:_Date>
<am:Member am:Descriptor="Clare Smith">
    <am:ID am:type="Member_ID">4588-D4</am:ID>
</am:Member>
<am:Members am:Descriptor="Jack Smith">
    <am:ID am:type="Member_ID">4588-D3</am:ID>
</am:Members>
<am:Members am:Descriptor="Colin Smith">
    <am:ID am:type="Member_ID">4588-D2</am:ID>
</am:Members>
<am:Previous_Members am:Descriptor="Kerry Smith">
    <am:ID am:type="Member_ID">4588-D1</am:ID>
</am:Previous_Members>
<am:Previous_Members am:Descriptor="Colin Smith">
    <am:ID am:type="Member_ID">4588-D2</am:ID>
</am:Previous_Members>
<am:Previous_Members am:Descriptor="Jack Smith">
    <am:ID am:type="Member_ID">4588-D3</am:ID>
</am:Previous_Members>
<am:Previous_Members am:Descriptor="Clare Smith">
    <am:ID am:type="Member_ID">4588-D4</am:ID>
</am:Previous_Members>

【问题讨论】:

    标签: xslt xml-parsing


    【解决方案1】:

    使用

    /*/am:Previous_Members[not(am:ID=/*/am:Member/am:ID)]
    

    这会选择 ID 不是当前成员 ID 的所有以前的团队成员。

    仅将模板应用于此 XPath 表达式选择的元素。

    更新

    所提供的 XML 文档同时包含:am:Memberam:Members——这可能是输入错误。

    更正上面的,使得只有am:Members,XML文档就变成了

    <am:Team xmlns:am="some:am">
        <am:First_Day>08/24/2012</am:First_Day>
        <am:_Date>08/23/2012</am:_Date>
        <am:Members am:Descriptor="Clare Smith">
            <am:ID am:type="Member_ID">4588-D4</am:ID>
        </am:Members>
        <am:Members am:Descriptor="Jack Smith">
            <am:ID am:type="Member_ID">4588-D3</am:ID>
        </am:Members>
        <am:Members am:Descriptor="Colin Smith">
            <am:ID am:type="Member_ID">4588-D2</am:ID>
        </am:Members>
        <am:Previous_Members am:Descriptor="Kerry Smith">
            <am:ID am:type="Member_ID">4588-D1</am:ID>
        </am:Previous_Members>
        <am:Previous_Members am:Descriptor="Colin Smith">
            <am:ID am:type="Member_ID">4588-D2</am:ID>
        </am:Previous_Members>
        <am:Previous_Members am:Descriptor="Jack Smith">
            <am:ID am:type="Member_ID">4588-D3</am:ID>
        </am:Previous_Members>
        <am:Previous_Members am:Descriptor="Clare Smith">
            <am:ID am:type="Member_ID">4588-D4</am:ID>
        </am:Previous_Members>
    </am:Team>
    

    XPath 表达式变为

    /*/am:Previous_Members[not(am:ID=/*/am:Members/am:ID)]
    

    并且,为了方便 OP,这里有一个完整的转换,它准确地复制了想要的节点:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:am="some:am" exclude-result-prefixes="am">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="am:Team/*"/>
    
     <xsl:template match="am:Previous_Members[not(am:ID=/*/am:Members/am:ID)] ">
         <xsl:copy-of select="."/>
     </xsl:template>
    </xsl:stylesheet>
    

    当对上述 XML 文档应用此转换时,会产生所需的正确结果

    <am:Previous_Members xmlns:am="some:am" am:Descriptor="Kerry Smith">
       <am:ID am:type="Member_ID">4588-D1</am:ID>
    </am:Previous_Members>
    

    【讨论】:

    • Dimitre,谢谢.. 如果这太基本的后续操作,我深表歉意,但是将其包含在输出中的代码是否会是
    • @JoeFoley,没有。只要有:&lt;xsl:apply-templates select="/*/am:Previous_Members[not(am:ID=/*/am:Member/am:ID)] "/&gt;。并且有一个匹配am:Previous_Members 的模板,该模板会为该特定成员生成 CSV 行。
    • 我一定很密集.. 我已经尝试了我认为应该做的事情,但就是没有得到它。我似乎得到了所有记录,而不仅仅是差异
    • @JoeFoley,我在工作——从现在开始 7 到 8 个小时。
    • @JoeFoley,请参阅我的答案的更新——您提供的 XML 不正确且具有误导性——我更正了它并相应地修改了 XPath 表达式。还展示了一个简单的完整转换,为您提供真正的基础。
    猜你喜欢
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 2011-01-13
    相关资源
    最近更新 更多