无法使用XSLT选择属性

时间:2012-07-24 18:48:32

标签: xslt

我需要选择Property1和SubProperty2并去掉任何其他属性。我需要进行此未来证明,以便添加到xml的任何新属性都不会破坏验证。默认情况下,必须剥离新的字段。

<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选择一个空节点。 *匹配似乎在我的比赛开始之前剥离了更深层次的对象。 我删除了*上的匹配,并选择了我的SubProperty值。那么,我如何选择子属性并仍然删除我不使用的所有内容。

感谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

有两个问题

<xsl:template match="*"/>

这会忽略任何没有重写,更具体的模板的元素。

因为顶部元素Root没有特定的模板,所以它与所有子树一起被忽略 - 这是完整的文档 - 根本不会产生任何输出。

第二个问题在这里

<xsl:template match="/Thing">

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

但是在提供的文档中,top元素名为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/>