展示两个XML文件之间的文本文件差异,使用XSLT1.0。

huangapple go评论51阅读模式
英文:

Show differences in a text file between two XML files with XSLT1.0

问题

以下是翻译好的部分:

1°) 检查文件2中是否有新的键和新的值,或者是否已删除键。

2°) 对于每个键,检查值是否已更改。

3°) 在文本文件中指出差异,对于每个差异,指出顶级父节点。

文件1

 <node>
    <node key="Network1">
      <node key="@IP" value="65.12.30.20"/>
      <node key="@MAC" value="62-42-85-74-21"/>
      <node key="PortNumber" value="12000"/>
      <node key="Location">
          <node key="House" value="Blue"/>
          <node key="Room" value="Green"/>
          <node key="Office" value="IT"/>
      </node>
     </node>
    
    <node key="Network2">
      <node key="@IP" value="15.58.12.36"/>
      <node key="@MAC" value="85-02-14-52-12"/>
      <node key="PortNumber" value="12000"/>
      <node key="Location">
          <node key="House" value="Blue"/>
          <node key="Room" value="Yellow"/>
          <node key="Office" value="IT"/>
       </node>
       </node>
 </node> 

文件2

<node>
<node key="Network1">
  <node key="@IP" value="65.12.30.20"/>
  <node key="@MAC" value="62-42-85-74-21"/>
  <node key="PortNumber" value="12001"/>
  <node key="Location">
      <node key="House" value="Blue"/>
      <node key="Room" value="Green"/>
      <node key="Office" value="HR"/>
      <node key="Rack" value="2"/>
   </node>
</node>

<node key="Network2">
  <node key="@IP" value="15.58.12.36"/>
  <node key="@MAC" value="14-85-13-74-36"/>
  <node key="PortNumber" value="12001"/>
  <node key="Location">
      <node key="House" value="Blue"/>
      <node key="Room" value="Yellow"/>
      <node key="Office" value="IT"/>
      <node key="Rack" value="1"/>
    </node>
  </node>
</node>

因此,我想指出差异。

@编辑

使用提供的解决方案,我在此示例中发现了一个错误。

<stackoverflow12>
	<node key="Test">
		<node key="keyA">
			<node key="A" value="A1">
				<node key="Name" value="Tim" />
			</node>
			<node key="A" value="A2">
				<node key="Name" value="Tom" />
			</node>
		</node>
	</node>
	
	<node key="Test">
		<node key="keyA">
			<node key="A" value="A1">
				<node key="Name" value="Tim" />
			</node>
			<node key="A" value="A2">
				<node key="Name" value="Tom" />
			</node>
		</node>
	</node>
</stackoverflow12>

这两个XML文件是相同的,但XSLT代码得到了以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<node key="Test">
    <node key="keyA">
        <node key="A" left-value="A1" right-value="A1"/>
        <node key="A" left-value="A2" right-value="A1"/>
    </node>
</node>

代码存在问题吗?

英文:

The opening file is file1 which is composed of a lot of network nodes with their children nodes.

Sometimes, the user can change something in the file1, either a value either add a new key and so a new value. The modification are so saved in a new file, file2.

What I would like to do, see the exemple, is :

1°) Check if, in the file2, there is new Keys and so new values or if keys have been deleted.

2°) Check, for each Key, if the value has changed.

3°) Point out the difference in a text file with, for each shift, the top parent node.

File 1

 &lt;node&gt;
    &lt;node key=&quot;Network1&quot;&gt;
      &lt;node key=&quot;@IP&quot; value=&quot;65.12.30.20&quot;/&gt;
      &lt;node key=&quot;@MAC&quot; value=&quot;62-42-85-74-21&quot;/&gt;
      &lt;node key=&quot;PortNumber&quot; value=&quot;12000&quot;/&gt;
      &lt;node key=&quot;Location&quot;&gt;
          &lt;node key=&quot;House&quot; value=&quot;Blue&quot;/&gt;
          &lt;node key=&quot;Room&quot; value=&quot;Green&quot;/&gt;
          &lt;node key=&quot;Office&quot; value=&quot;IT&quot;/&gt;
      &lt;/node&gt;
     &lt;/node&gt;
    
    &lt;node key=&quot;Network2&quot;&gt;
      &lt;node key=&quot;@IP&quot; value=&quot;15.58.12.36&quot;/&gt;
      &lt;node key=&quot;@MAC&quot; value=&quot;85-02-14-52-12&quot;/&gt;
      &lt;node key=&quot;PortNumber&quot; value=&quot;12000&quot;/&gt;
      &lt;node key=&quot;Location&quot;&gt;
          &lt;node key=&quot;House&quot; value=&quot;Blue&quot;/&gt;
          &lt;node key=&quot;Room&quot; value=&quot;Yellow&quot;/&gt;
          &lt;node key=&quot;Office&quot; value=&quot;IT&quot;/&gt;
       &lt;/node&gt;
       &lt;/node&gt;
 &lt;/node&gt; 

File 2

&lt;node&gt;
&lt;node key=&quot;Network1&quot;&gt;
  &lt;node key=&quot;@IP&quot; value=&quot;65.12.30.20&quot;/&gt;
  &lt;node key=&quot;@MAC&quot; value=&quot;62-42-85-74-21&quot;/&gt;
  &lt;node key=&quot;PortNumber&quot; value=&quot;12001&quot;/&gt;
  &lt;node key=&quot;Location&quot;&gt;
      &lt;node key=&quot;House&quot; value=&quot;Blue&quot;/&gt;
      &lt;node key=&quot;Room&quot; value=&quot;Green&quot;/&gt;
      &lt;node key=&quot;Office&quot; value=&quot;HR&quot;/&gt;
      &lt;node key=&quot;Rack&quot; value=&quot;2&quot;/&gt;
   &lt;/node&gt;
&lt;/node&gt;

&lt;node key=&quot;Network2&quot;&gt;
  &lt;node key=&quot;@IP&quot; value=&quot;15.58.12.36&quot;/&gt;
  &lt;node key=&quot;@MAC&quot; value=&quot;14-85-13-74-36&quot;/&gt;
  &lt;node key=&quot;PortNumber&quot; value=&quot;12001&quot;/&gt;
  &lt;node key=&quot;Location&quot;&gt;
      &lt;node key=&quot;House&quot; value=&quot;Blue&quot;/&gt;
      &lt;node key=&quot;Room&quot; value=&quot;Yellow&quot;/&gt;
      &lt;node key=&quot;Office&quot; value=&quot;IT&quot;/&gt;
      &lt;node key=&quot;Rack&quot; value=&quot;1&quot;/&gt;
    &lt;/node&gt;
  &lt;/node&gt;
&lt;/node&gt;

So, I would like to point out the differences.

@EDIT

With the solution proposed, I've found a bug with this example.

&lt;stackoverflow12&gt;
	&lt;node key=&quot;Test&quot;&gt;
		&lt;node key=&quot;keyA&quot;&gt;
			&lt;node key=&quot;A&quot; value=&quot;A1&quot;&gt;
				&lt;node key=&quot;Name&quot; value=&quot;Tim&quot; /&gt;
			&lt;/node&gt;
			&lt;node key=&quot;A&quot; value=&quot;A2&quot;&gt;
				&lt;node key=&quot;Name&quot; value=&quot;Tom&quot; /&gt;
			&lt;/node&gt;
		&lt;/node&gt;
	&lt;/node&gt;
	
	&lt;node key=&quot;Test&quot;&gt;
		&lt;node key=&quot;keyA&quot;&gt;
			&lt;node key=&quot;A&quot; value=&quot;A1&quot;&gt;
				&lt;node key=&quot;Name&quot; value=&quot;Tim&quot; /&gt;
			&lt;/node&gt;
			&lt;node key=&quot;A&quot; value=&quot;A2&quot;&gt;
				&lt;node key=&quot;Name&quot; value=&quot;Tom&quot; /&gt;
			&lt;/node&gt;
		&lt;/node&gt;
	&lt;/node&gt;
&lt;/stackoverflow12&gt;

The two XML Files are the same but the XSLT code get :

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;node key=&quot;Test&quot;&gt;
    &lt;node key=&quot;keyA&quot;&gt;
        &lt;node key=&quot;A&quot; left-value=&quot;A1&quot; right-value=&quot;A1&quot;/&gt;
        &lt;node key=&quot;A&quot; left-value=&quot;A2&quot; right-value=&quot;A1&quot;/&gt;
    &lt;/node&gt;
&lt;/node&gt;

What's the problem with the code ?

答案1

得分: 2

你需要的输出包括两个文件,它们缺少XML语法所需的闭合标签。建议不直接创建这两个文件,而是建议创建一个"中间"的XML文件,其中包含具有left-valueright-value的节点,如果两个输入文件之间的值不同,以及left-noderight-node,如果某个键只存在于其中一个文件中。以下样式表会递归地计算这样一个中间XML文件。它会为每个在两个输入文件中相同的具有子节点的节点产生多余的节点,比如&lt;node key=&quot;...&quot;&gt;(这在你的示例中并不会发生)。这些可以在第二次遍历时移除,或者在将中间格式转换为你所需的输出时简单地跳过。

样式表期望一个单一的XML输入,将你的两个输入文件合并如下:

&lt;stackoverflow-75629991&gt;
  &lt;node&gt;
    &lt;!-- File 1 --&gt;
  &lt;/node&gt;
  &lt;node&gt;
    &lt;!-- File 2 --&gt;
  &lt;/node&gt;
&lt;/stackoverflow-75629991&gt;

以下是样式表:

&lt;xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
  &lt;xsl:output method=&quot;xml&quot; indent=&quot;yes&quot; /&gt;
  &lt;xsl:template match=&quot;/*&quot;&gt;
    &lt;xsl:apply-templates select=&quot;node[1]&quot;&gt;
      &lt;xsl:with-param name=&quot;others&quot; select=&quot;node[2]&quot; /&gt;
    &lt;/xsl:apply-templates&gt;
  &lt;/xsl:template&gt;
  &lt;xsl:template match=&quot;node&quot;&gt;
    &lt;xsl:param name=&quot;others&quot; /&gt;
    &lt;xsl:variable name=&quot;other&quot; select=&quot;$others[not(@key) or @key=current()/@key]&quot; /&gt;
    &lt;xsl:choose&gt;
      &lt;xsl:when test=&quot;@value != $other/@value&quot;&gt;
        &lt;node key=&quot;{@key}&quot; left-value=&quot;{@value}&quot; right-value=&quot;{$other/@value}&quot; /&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:when test=&quot;$other and not(@value)&quot;&gt;
        &lt;node&gt;
          &lt;xsl:copy-of select=&quot;@key&quot; /&gt;
          &lt;xsl:apply-templates select=&quot;node&quot;&gt;
            &lt;xsl:with-param name=&quot;others&quot; select=&quot;$other/node&quot; /&gt;
          &lt;/xsl:apply-templates&gt;
          &lt;xsl:for-each select=&quot;$other/node[not(@key=current()/node/@key)]&quot;&gt;
            &lt;right-node&gt;
              &lt;xsl:copy-of select=&quot;@key | @value | node&quot;/&gt;
            &lt;/right-node&gt;
          &lt;/xsl:for-each&gt;
        &lt;/node&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:when test=&quot;not($other)&quot;&gt;
        &lt;left-node&gt;
          &lt;xsl:copy-of select=&quot;@key | @value | node&quot;/&gt;
        &lt;/left-node&gt;
      &lt;/xsl:when&gt;
    &lt;/xsl:choose&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;

以下是它生成的中间XML文件的输出:

&lt;node&gt;
   &lt;node key=&quot;Network1&quot;&gt;
      &lt;node key=&quot;PortNumber&quot; left-value=&quot;12000&quot; right-value=&quot;12001&quot;/&gt;
      &lt;node key=&quot;Location&quot;&gt;
         &lt;node key=&quot;Office&quot; left-value=&quot;IT&quot; right-value=&quot;HR&quot;/&gt;
         &lt;right-node key=&quot;Rack&quot; value=&quot;2&quot;/&gt;
      &lt;/node&gt;
   &lt;/node&gt;
   &lt;node key=&quot;Network2&quot;&gt;
      &lt;node key=&quot;@MAC&quot; left-value=&quot;85-02-14-52-12&quot; right-value=&quot;14-85-13-74-36&quot;/&gt;
      &lt;node key=&quot;PortNumber&quot; left-value=&quot;12000&quot; right-value=&quot;12001&quot;/&gt;
      &lt;node key=&quot;Location&quot;&gt;
         &lt;right-node key=&quot;Rack&quot; value=&quot;1&quot;/&gt;
      &lt;/node&gt;
   &lt;/node&gt;
&lt;/node&gt;
英文:

Your desired output consists of two files that lack the closing tags demanded by the XML syntax. Rather than create that directly, I suggest creating an "intermediate" XML file that contains nodes with a left-value and a right-value if the value differs between the two input files and a left-node or right-node if the key exists only in one file. The following stylesheet computes such an intermediate XML file recursively. It would produce superfluous nodes like &lt;node key=&quot;...&quot;&gt; for every node with children that is the same in the two input files (which does not occur in your example). These can be removed with a second pass or simply skipped over when the intermediate format is converted into your desired output.

The stylesheet expects a single XML input that combines both your input files like so:

&lt;stackoverflow-75629991&gt;
  &lt;node&gt;
    &lt;!-- File 1 --&gt;
  &lt;/node&gt;
  &lt;node&gt;
    &lt;!-- File 2 --&gt;
  &lt;/node&gt;
&lt;/stackoverflow-75629991&gt;

Here is the stylesheet:

&lt;xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
  &lt;xsl:output method=&quot;xml&quot; indent=&quot;yes&quot; /&gt;
  &lt;xsl:template match=&quot;/*&quot;&gt;
    &lt;xsl:apply-templates select=&quot;node[1]&quot;&gt;
      &lt;xsl:with-param name=&quot;others&quot; select=&quot;node[2]&quot; /&gt;
    &lt;/xsl:apply-templates&gt;
  &lt;/xsl:template&gt;
  &lt;xsl:template match=&quot;node&quot;&gt;
    &lt;xsl:param name=&quot;others&quot; /&gt;
    &lt;xsl:variable name=&quot;other&quot; select=&quot;$others[not(@key) or @key=current()/@key]&quot; /&gt;
    &lt;xsl:choose&gt;
      &lt;xsl:when test=&quot;@value != $other/@value&quot;&gt;
        &lt;node key=&quot;{@key}&quot; left-value=&quot;{@value}&quot; right-value=&quot;{$other/@value}&quot; /&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:when test=&quot;$other and not(@value)&quot;&gt;
        &lt;node&gt;
          &lt;xsl:copy-of select=&quot;@key&quot; /&gt;
          &lt;xsl:apply-templates select=&quot;node&quot;&gt;
            &lt;xsl:with-param name=&quot;others&quot; select=&quot;$other/node&quot; /&gt;
          &lt;/xsl:apply-templates&gt;
          &lt;xsl:for-each select=&quot;$other/node[not(@key=current()/node/@key)]&quot;&gt;
            &lt;right-node&gt;
              &lt;xsl:copy-of select=&quot;@key | @value | node&quot;/&gt;
            &lt;/right-node&gt;
          &lt;/xsl:for-each&gt;
        &lt;/node&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:when test=&quot;not($other)&quot;&gt;
        &lt;left-node&gt;
          &lt;xsl:copy-of select=&quot;@key | @value | node&quot;/&gt;
        &lt;/left-node&gt;
      &lt;/xsl:when&gt;
    &lt;/xsl:choose&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;

And here is the intermediate XML file it produces as output:

&lt;node&gt;
   &lt;node key=&quot;Network1&quot;&gt;
      &lt;node key=&quot;PortNumber&quot; left-value=&quot;12000&quot; right-value=&quot;12001&quot;/&gt;
      &lt;node key=&quot;Location&quot;&gt;
         &lt;node key=&quot;Office&quot; left-value=&quot;IT&quot; right-value=&quot;HR&quot;/&gt;
         &lt;right-node key=&quot;Rack&quot; value=&quot;2&quot;/&gt;
      &lt;/node&gt;
   &lt;/node&gt;
   &lt;node key=&quot;Network2&quot;&gt;
      &lt;node key=&quot;@MAC&quot; left-value=&quot;85-02-14-52-12&quot; right-value=&quot;14-85-13-74-36&quot;/&gt;
      &lt;node key=&quot;PortNumber&quot; left-value=&quot;12000&quot; right-value=&quot;12001&quot;/&gt;
      &lt;node key=&quot;Location&quot;&gt;
         &lt;right-node key=&quot;Rack&quot; value=&quot;1&quot;/&gt;
      &lt;/node&gt;
   &lt;/node&gt;
&lt;/node&gt;

huangapple
  • 本文由 发表于 2023年3月4日 01:07:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75629991.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定