1

我有一个案例,其中有 2 个相同结构的 XML 变量。我想知道两者之间的区别。

假设 V1(代表新记录)具有元素 a1、a2、a3、a4 和 V2(代表已经存在的记录)具有元素 a5、a7、a3

在这里,V1 中的变量 a3 存在于 V2 中,所以我想摆脱那个变量,我想要一个只包含 {a1, a2, a4} 的新变量

这是我的 2 个 XML 变量

第一的 :

<ReadUsersResponse>
    <User>
        <EmailAddress>aaa</EmailAddress>
        <Name>a</Name>
        <ObjectId>101</ObjectId>
    </User>
    <User>
        <EmailAddress>bbb</EmailAddress>
        <Name>b</Name>
        <ObjectId>103</ObjectId>
    </User>
    <User>
        <EmailAddress>ccc</EmailAddress>
        <Name>c</Name>
        <ObjectId>104</ObjectId>
    </User>
</ReadUsersResponse>

第二 :

<ReadUsersResponse>
    <User>
        <EmailAddress>ddd</EmailAddress>
        <Name>d</Name>
        <ObjectId>104</ObjectId>
    </User>
    <User>
        <EmailAddress>bbb</EmailAddress>
        <Name>b</Name>
        <ObjectId>103</ObjectId>
    </User>
    <User>
        <EmailAddress>ccc</EmailAddress>
        <Name>c</Name>
        <ObjectId>107</ObjectId>
    </User>
</ReadUsersResponse>

比较每个中的 ObjectId 这就是我想要的:(修剪 ObjectId 103,因为它已经在 Variable2 中可用)

<ReadUsersResponse>
    <User>
        <EmailAddress>aaa</EmailAddress>
        <Name>a</Name>
        <ObjectId>101</ObjectId>
    </User>
    <User>
        <EmailAddress>ccc</EmailAddress>
        <Name>c</Name>
        <ObjectId>104</ObjectId>
    </User>
</ReadUsersResponse>

我试过了,但我做不到。

我遵循的方法是首先将这 2 个 XML 变量合并为 1 个变量,在 2 个单独的标签中 Ex ..first Var... ..second Var...

我对此有疑问,无法弄清楚。这是正确的方法吗?或者有什么替代方法吗?有谁知道解决方案。

提前致谢

此致

4

2 回答 2

0

尝试这样的事情:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:key name="kuser" match="User" 
             use="concat(ObjectId,'#', EmailAddress, '#', Name)" />
    <xsl:variable name="u2" select="document('doc_2.xml')"/>

    <xsl:template match="User">
        <xsl:variable name="user_found">
            <xsl:apply-templates select="$u2/ReadUsersResponse" mode="checkuser" >
                <xsl:with-param name="user" select="." />
            </xsl:apply-templates>
        </xsl:variable>
        <xsl:if test="$user_found != 'true'">
            <xsl:copy>
                <xsl:apply-templates />
            </xsl:copy>
        </xsl:if>
    </xsl:template>

    <xsl:template match="ReadUsersResponse" mode="checkuser">
        <xsl:param name="user"/>
        <xsl:if test="key('kuser', concat($user/ObjectId,'#', $user/EmailAddress, '#', $user/Name))" >
            <xsl:text>true</xsl:text>
    </xsl:if>
    </xsl:template>
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="@* | node() " />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

这将生成以下输出:

<ReadUsersResponse>
        <User>
                <EmailAddress>aaa</EmailAddress>
                <Name>a</Name>
                <ObjectId>101</ObjectId>
        </User>

        <User>
                <EmailAddress>ccc</EmailAddress>
                <Name>c</Name>
                <ObjectId>104</ObjectId>
        </User>
</ReadUsersResponse>

他们的键值use="concat(ObjectId,'#', EmailAddress, '#', Name)"可以根据他应该检查用户的哪一部分来调整。

对于一些解释有: 例如在单独的文档中查找表
一个要点是为每个加载的源文档准备一个单独的索引(使用 document() 函数)。

于 2013-05-07T06:37:19.840 回答
0

另一个解决方案是:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:param name="first">
    <ReadUsersResponse>
      <User>
        <EmailAddress>aaa</EmailAddress>
        <Name>a</Name>
        <ObjectId>101</ObjectId>
      </User>
      <User>
        <EmailAddress>bbb</EmailAddress>
        <Name>b</Name>
        <ObjectId>103</ObjectId>
      </User>
      <User>
        <EmailAddress>ccc</EmailAddress>
        <Name>c</Name>
        <ObjectId>104</ObjectId>
      </User>
    </ReadUsersResponse>
  </xsl:param>
  <xsl:param name="second">
    <ReadUsersResponse>
      <User>
        <EmailAddress>ddd</EmailAddress>
        <Name>d</Name>
        <ObjectId>104</ObjectId>
      </User>
      <User>
        <EmailAddress>bbb</EmailAddress>
        <Name>b</Name>
        <ObjectId>103</ObjectId>
      </User>
      <User>
        <EmailAddress>ccc</EmailAddress>
        <Name>c</Name>
        <ObjectId>107</ObjectId>
      </User>
    </ReadUsersResponse>
  </xsl:param>

  <xsl:key name="User" match="User" use="ObjectId"/>
  <xsl:template match="/">
    <xsl:for-each select="$first//User">
      <xsl:variable name="ObjectId" select="ObjectId"/>
      <xsl:variable name="User">
        <xsl:copy-of select="."/>
      </xsl:variable>
      <xsl:message>
        <xsl:copy-of select="$User"/>
      </xsl:message>
      <xsl:choose>
        <xsl:when
          test="$ObjectId = $second//User/ObjectId[preceding-sibling::EmailAddress = $User/User/EmailAddress]"/>
        <xsl:otherwise>
          <xsl:copy>
            <xsl:copy-of select="."/>
          </xsl:copy>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
于 2013-05-07T06:52:05.143 回答