【问题标题】:How best to merge data with xslt如何最好地使用 xslt 合并数据
【发布时间】:2014-08-27 17:34:38
【问题描述】:

我希望有人能在这方面为我指明正确的方向。我试图以我能想到的最简单的形式来隔离我的问题。在解析文件时:

<?xml version="1.0" encoding="UTF-8"?>
<Master>
    <Info>
        <Info1></Info1>
        <Info2></Info2>
        <Info3></Info3>
        <Offer>
            <Id>1a</Id>
            <Field1></Field1>
            <Field2></Field2>
            <Field3></Field3>
        </Offer>
        <Offer>
            <Id>3a</Id>
            <Field1></Field1>
            <Field2></Field2>
            <Field3></Field3>
        </Offer>
    </Info>
</Master>

我需要将它与类似的文件进行比较:

<?xml version="1.0" encoding="UTF-8"?>
<Old>
    <Info>
        <Info1></Info1>
        <Info2></Info2>
        <Info3></Info3>
        <Offer>
            <Id>1a</Id>
            <Field1></Field1>
            <Field2></Field2>
            <Field3></Field3>
        </Offer>
        <Offer>
            <Id>2a</Id>
            <Field1></Field1>
            <Field2></Field2>
            <Field3></Field3>
        </Offer>
    </Info>
</Old>

使用字段作为键,我想生成以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<Merged>
    <Info>  ##from Master
        <Info1></Info1>
        <Info2></Info2>
        <Info3></Info3>
        <Offer>     ##from Master
            <Id>1a</Id>
            <Field1></Field1>
            <Field2></Field2>
            <Field3></Field3>
            <Action>Update</Action>
        </Offer>
        <Offer>     ##from Old
            <Id>2a</Id>
            <Field1></Field1>
            <Field2></Field2>
            <Field3></Field3>
            <Action>Delete</Action>
        </Offer>
        <Offer>     ##from Master
            <Id>3a</Id>
            <Field1></Field1>
            <Field2></Field2>
            <Field3></Field3>
            <Action>Add</Action>
         </Offer>
    </Info>
</Merged>

1a 在 Master 和 Old 中都匹配,因此它成为更新操作,2a 存在于 Old 但不存在于 Master 中是否成为删除操作,3a 仅存在于 Master 中,因此它成为添加操作。和数据始终来自主数据(当然删除情况除外)。

提前感谢您的帮助。

【问题讨论】:

  • 在编写自己的合并算法之前,请尝试Oliver Becker's。如果它产生您想要的输出,请告诉我们。
  • 请注明 XSLT 1.0 或 2.0。
  • 感谢您的建议。我正在研究它,我当然不是专家,但似乎需要大量的返工才能产生我需要的结果。我正在查看 A 与 B 相交(我的更新)、A 除了 B(我的添加)和 B 除了 A(我的删除),但我不确定如何应用它

标签: xml xslt merge xslt-2.0


【解决方案1】:

这似乎很简单(或者我可能误解了要求):

XSLT 2.0

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

<xsl:variable name="master" select="document(base-uri())" />
<xsl:variable name="old" select="document('old.xml')"/>

<xsl:key name="offer" match="Offer" use="Id" />

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

<xsl:template match="Info">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <xsl:apply-templates select="$old/Old/Info/Offer[not(key('offer', Id, $master))]" mode="delete"/>
    </xsl:copy>
</xsl:template>

 <xsl:template match="Offer">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
         <Action>
            <xsl:choose>
                <xsl:when test="key('offer', Id, $old)">Update</xsl:when>
                <xsl:otherwise>Add</xsl:otherwise>
            </xsl:choose>
         </Action>
    </xsl:copy>
</xsl:template>

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

</xsl:stylesheet>

这里假设 Master.xml 文件是正在处理的文件。

【讨论】:

  • 解决方案实际上可能很简单,但我仍在学习。我今天已经没时间了,但明天肯定会查看您的解决方案并进行更新。再次感谢,非常感谢。
  • 通过提供的示例,我能够让它工作。
猜你喜欢
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多