没有值的XSL副本是否可能?

时间:2018-02-26 09:30:21

标签: xslt

我想比较两个xmls。 1.首先比较XML结构/模式。 2.比较值。

我使用超越比较工具进行比较。由于这两个xmls是不同的值,因此在比较报告中存在很多差异,对此我并不感兴趣。因为,我现在的重点是只比较结构/架构。

我尝试通过以下模板复制xmls,以及其他模板。但每次都有价值观。

我在google上浏览,xsl-copy命令本身会复制所选节点/元素的所有内容。

有什么方法可以过滤掉值,只复制架构?

我的数据:

<root>
<Child1>xxxx</Child1>
<Child2>yyy</Child2>
<Child3>
<GrandChild1>dddd<GrandChild1>
<GrandChild2>erer<GrandChild2>
</Child3>
</root>

使用的模板:

<xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>


  <!-- for all elements (tags) -->  
  <xsl:template match="*">
    <!-- create a copy of the tag (without attributes and children) in the output -->   
    <xsl:copy>
      <!-- For all attributes of the current tag -->
      <xsl:for-each select="@*">
        <xsl:sort select="name( . )" order="ascending" case-order="lower-first" />
        <xsl:copy/>
      </xsl:for-each>
      <!-- recurse through all child tags -->
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="text()|comment()|processing-instruction()">
    <xsl:copy/>
  </xsl:template>

OutPut要求:

像...这样的东西。

<root>
<Child1></Child1>
<Child2></Child2>
<Child3>
<GrandChild1><GrandChild1>
<GrandChild2><GrandChild2>
</Child3>
</root>  

1 个答案:

答案 0 :(得分:1)

目前,您有一个匹配text()的模板来复制它。您需要做的是从该模板中删除此匹配,并使用单独的模板匹配,仅匹配非空白文本,并将其删除。

<xsl:template match="comment()|processing-instruction()">
  <xsl:copy/>
</xsl:template>

<xsl:template match="text()[normalize-space()]" />

对于仅限空格的文本(在缩进中使用),这些将由XSLT&#39; S内置模板匹配。

对于属性,使用xsl:attribute创建一个没有值的新属性,而不是使用将复制整个属性的xsl:copy

<xsl:attribute name="{name()}" />

请注意使用属性值模板(花括号)来指示要计算表达式以获取要使用的字符串。

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <!-- for all elements (tags) -->  
  <xsl:template match="*">
    <!-- create a copy of the tag (without attributes and children) in the output -->   
    <xsl:copy>
      <!-- For all attributes of the current tag -->
      <xsl:for-each select="@*">
        <xsl:sort select="name( . )" order="ascending" case-order="lower-first" />
        <xsl:attribute name="{name()}" />
      </xsl:for-each>
      <!-- recurse through all child tags -->
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="comment()|processing-instruction()">
    <xsl:copy/>
  </xsl:template>

  <xsl:template match="text()[normalize-space()]" />
</xsl:stylesheet>

另请注意,属性在XML中被认为是无序的,因此尽管您有用于对属性进行排序的代码,并且它们可能会以正确的顺序出现,但您无法保证。