0

我需要选择 Property1 和 SubProperty2 并删除任何其他属性。我需要做这个未来的证明,以便添加到 xml 的任何新属性都不会破坏验证。默认情况下,iow 的新字段必须被剥离。

<Root>
    <Property1/>
    <Property2/>
    <Thing>
        <SubProperty1/>
        <SubProperty2/>
    </Thing>
    <VariousProperties/>
</Root>

所以在我的 xslt 中我这样做了:

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

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

 <xsl:template match="*" />

最后一行应该去掉我没有定义为选中的任何内容。

这适用于选择我的 property1,但它总是为 SubProperty 选择一个空节点。* 上的匹配似乎在我对它们的匹配起作用之前去除了更深的对象。我删除了 * 上的匹配项,它选择了带有值的子属性。那么,我怎样才能选择子属性并仍然剥离我不使用的所有内容。

感谢您的任何建议。

4

1 回答 1

0

有两个问题

<xsl:template match="*"/>

这将忽略任何没有覆盖的、更具体的模板的元素。

因为顶部元素没有特定的模板,所以Root它连同它的所有子树(即完整的文档)一起被忽略,根本不产生任何输出。

第二个问题在这里

<xsl:template match="/Thing">

此模板匹配名为 的顶部元素Thing

但是在提供的文档中,顶部元素被命名为Root. 因此,上面的模板与提供的 XML 文档中的任何节点都不匹配,并且永远不会被选中执行。由于其主体内的代码应该生成SubProperty1,因此不会生成这样的输出。

解决方案

改变

<xsl:template match="*"/>

<xsl:template match="text()"/>

并改变

<xsl:template match="/Thing">

<xsl:template match="Thing">

整个转变变成

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

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

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

     <xsl:template match="text()" />
</xsl:stylesheet>

并且当应用于以下 XML 文档时(由于提供的格式严重错误,必须对其进行修复):

<Root>
    <Property1/>
    <Property2/>
    <Thing>
        <SubProperty1/>
        <SubProperty2/>
    </Thing>
    <VariousProperties/>
</Root>

现在的结果就是想要的

<Property1/>
<SubProperty1/>
于 2012-07-25T03:43:58.843 回答