简体   繁体   English

如何使用 XSLT 基于输入 XML 请求的相同属性从 XML 文件中删除公共节点?

[英]How to remove common nodes from XML files based on same attributes of input XML request using XSLT?

I have two XMLs:我有两个 XML:

XML1.xml which will be as an input request. XML1.xml将作为输入请求。

<ConnectorConfig>
<service uri="/gen5">
<routeUrl>http://localhost:3003/v1</routeUrl>
</service>
<service uri="/gen6">
<routeUrl>http://localhost:3003/v61</routeUrl>
</service>
</ConnectorConfig> 

XML2.xml which will be stored xml file. XML2.xml将存储 xml 文件。

<ConnectorConfig>
<service uri="/gen5">
<routeUrl>http://localhost:3003/v5</routeUrl>
</service>
<service uri="/gen6">
<routeUrl>http://localhost:3003/v6</routeUrl>
</service>
<service uri="/gen7">
<routeUrl>http://localhost:3003/v7</routeUrl>
</service>
<service uri="/gen8">
<routeUrl>http://localhost:3003/v7</routeUrl>
</service>
</ConnectorConfig>

Output which i need is to get all the elements of XML2.xml except for the element having same service attribute in XML1.xml .我需要的Output是获取 XML2.xml 的所有元素,但在XML1.xml中具有相同服务属性的元素除外

Desired Output:所需的 Output:

<ConnectorConfig>
    <service uri="/gen7">
        <routeUrl>http://localhost:3003/v7</routeUrl>
    </service>
    <service uri="/gen8">
        <routeUrl>http://localhost:3003/v7</routeUrl>
    </service>
</ConnectorConfig>

This is what i tried.这是我尝试过的。

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

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

  <xsl:template match="ConnectorConfig">
  <xsl:copy> 
     <xsl:variable name="item" select="document('XML2.xml')/ConnectorConfig"/>  
     <xsl:variable name="current" select="."/> 

   <xsl:for-each select="$item/service"> 
      <xsl:variable name="savedUri" select="@uri"/> 
 
        <xsl:if test="$current/service[@uri!=$savedUri]">
          <xsl:apply-templates select="."/>
        </xsl:if> 

   </xsl:for-each>  
  </xsl:copy>
  </xsl:template>

 </xsl:stylesheet>

Output which i got for input request XML1.xml is:我为输入请求XML1.xml 得到的 Output是:

<ConnectorConfig>
    <service uri="/gen5">
        <routeUrl>http://localhost:3003/v5</routeUrl>
    </service>
    <service uri="/gen6">
        <routeUrl>http://localhost:3003/v6</routeUrl>
    </service>
    <service uri="/gen7">
        <routeUrl>http://localhost:3003/v7</routeUrl>
    </service>
    <service uri="/gen8">
        <routeUrl>http://localhost:3003/v7</routeUrl>
    </service>
</ConnectorConfig> 

But when i tried for same implementation with input XML1a.xml as:但是当我尝试使用输入XML1a.xml作为相同的实现时:

<ConnectorConfig>
<service uri="/gen5">
<routeUrl>http://localhost:3003/v1</routeUrl>
</service>
</ConnectorConfig> 

I received desired output which is shown below.我收到了所需的 output,如下所示。

<ConnectorConfig>
    <service uri="/gen6">
        <routeUrl>http://localhost:3003/v6</routeUrl>
    </service>
    <service uri="/gen7">
        <routeUrl>http://localhost:3003/v7</routeUrl>
    </service>
    <service uri="/gen8">
        <routeUrl>http://localhost:3003/v7</routeUrl>
    </service>
</ConnectorConfig>

In above, the output result contains all the elements of XML2.xml except one having /gen5 as common attribute for service element in input XML1a.xml .在上面,output 结果包含 XML2.xml 的所有元素,除了一个具有/gen5作为输入XML1a.Z0F635D0E0F3874FFF8B581C132E6C7中服务元素的公共属性的元素。

From the above what i came to known is that for single service element in input request, i'm getting the desired result but for multiple elements its fails.从上面我知道的是,对于输入请求中的单个服务元素,我得到了想要的结果,但是对于多个元素它失败了。

What is the mistake i'm doing?我在做什么错误? Please help.请帮忙。

How about simply:简单地说:

XSLT 1.0 XSLT 1.0

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

<xsl:template match="ConnectorConfig">
    <xsl:variable name="local-uris" select="service/@uri" />
    <xsl:copy> 
        <xsl:copy-of select="document('XML2.xml')/ConnectorConfig/service[not(@uri=$local-uris)]"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Note that the predicate:请注意谓词:

[not(@uri=$local-uris)]

is not the same as:一样:

[@uri!=$local-uris]

The former passes only nodes whose uri does not have a matching value in $local-uris .前者仅传递uri$local-uris中没有匹配值的节点。

The latter passes any node whose uri is not equal to at least one uri in $local-uris .后者传递任何uri不等于$local-uris中至少一个uri的节点。 In the given example, all nodes pass this test.在给定的示例中,所有节点都通过了此测试。 If you reduce $local-uris to a single value, then all nodes will pass this test except the one that is equal to the single value.如果将$local-uris减少为单个值,则所有节点都将通过此测试,除了等于单个值的节点。 This should explain your own observations.这应该解释你自己的观察。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM