如何使用模式转换xml文档

时间:2014-04-12 11:04:04

标签: xml xslt

我有一个XML文档,所有节点都是“a”,下面输出的格式是“b”,“c”节点

 
<a>

   <a>

     <a>

           <a/>

     </a>

  </a>

 <a/>

</a>
 
<b> 

    <c>

         <b>

            <c/>

         </b>

    </c>


  <c/>

</b>

如何转换为输出,因为我脑子里没有想法。

我正在尝试使用模式,但模式并不清楚如何为每个元素使用模式

或者我是否需要使用条件,如if或何时检查节点并更改节点的名称

在XSLT中使用了一些替换命令,因为我需要在这里使用一对模板来解决这个问题

问题

2 个答案:

答案 0 :(得分:1)

使用

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

<xsl:template match="a[count(ancestor::a) mod 2 = 0]">
  <b>
    <xsl:apply-templates select="@* | node()"/>
  </b>
</xsl:template>

<xsl:template match="a[count(ancestor::a) mod 2 = 1]">
  <c>
    <xsl:apply-templates select="@* | node()"/>
  </c>
</xsl:template>

</xsl:stylesheet>

我得到了输出

<b>

   <c>

     <b>

           <c/>

     </b>

  </c>

 <c/>

</b>

输入

<a>

   <a>

     <a>

           <a/>

     </a>

  </a>

 <a/>

</a>

我为您发布的输入样本获得了所需的结果。您需要向更多文本解释您希望实现的目标我目前尚不确定是否只需要该级别来决定a是转换为b还是c

答案 1 :(得分:1)

如果你真的,真的想使用模式,这是一个如何做的例子

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

   <xsl:template match="/">
      <xsl:apply-templates select="a" mode="b"/>
   </xsl:template>

   <xsl:template match="a" mode="b">
      <b>
         <xsl:apply-templates select="a" mode="c"/>
      </b>
   </xsl:template>

   <xsl:template match="a" mode="c">
      <c>
         <xsl:apply-templates select="a" mode="b"/>
      </c>
   </xsl:template>
</xsl:stylesheet>

因此,首先,模板<xsl:template match="/">与文档节点匹配。然后,您可以在模式&#34; b&#34;

中选择第一个 a 元素
<xsl:apply-templates select="a" mode="b"/>

此模式有相应的模板匹配

<xsl:template match="a" mode="b">

在此内容中,您创建一个 b 元素,然后选择子元素,这次使用模式&#34; c&#34;

<xsl:apply-templates select="a" mode="c"/>

同样,此模板会输出 c 元素,但之后会切换回模式&#34; b&#34;中选择 a 元素,因此这两个模板相互交替。

如果没有该模式,您将拥有两个与 a

元素匹配的模板
<xsl:template match="a">

有两个匹配相同元素的模板被认为是错误,因为XSLT处理器无法决定使用哪个。

当然,如果您假设输出 b 是默认行为,那么您可以稍微简化一下,那么这也可行

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

   <xsl:template match="a">
      <b>
         <xsl:apply-templates select="a" mode="c"/>
      </b>
   </xsl:template>

   <xsl:template match="a" mode="c">
      <c>
         <xsl:apply-templates select="a"/>
      </c>
   </xsl:template>
</xsl:stylesheet>

如上所述,正如Martin Honnen指出的那样,你不需要在这方面使用模式。如果您已经有办法使用XPath表达式区分 a 元素,那么您可以轻松地使用它。