Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用xslt转换嵌套的xml项_Xml_Xslt - Fatal编程技术网

使用xslt转换嵌套的xml项

使用xslt转换嵌套的xml项,xml,xslt,Xml,Xslt,如何使用xslt转换嵌套的XML元素,保持结构不变 假设我有这样一个XML文档: <?xml version="1.0" encoding="UTF-8"?> <root> <node> </node> <node> <node> <node> </node> </node> </node> </root>

如何使用xslt转换嵌套的XML元素,保持结构不变

假设我有这样一个XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <node>
  </node>
  <node>
    <node>
      <node>
      </node>
    </node>
  </node>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <element>
    </element>
    <element>
      <element>
        <element>
        </element>
      </element>
    </element>
</root>

我想得到这样的东西:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <node>
  </node>
  <node>
    <node>
      <node>
      </node>
    </node>
  </node>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <element>
    </element>
    <element>
      <element>
        <element>
        </element>
      </element>
    </element>
</root>

我应该使用哪种xslt

谢谢


<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/root">
    <root>
      <xsl:apply-templates />
    </root>
  </xsl:template>
  <xsl:template match="node">
    <element>
      <xsl:apply-templates />
    </element>
  </xsl:template>
</xsl:stylesheet>

关键是
apply templates
标记以递归方式处理标记内容。

在XSLT中实现这一点的方法是(使用and push样式)

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

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

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

当此转换应用于提供的XML文档时

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

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

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

生成所需的正确结果

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

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

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

注意事项

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

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

 <xsl:template match="node">
  <element>
    <xsl:apply-templates select="node()|@*"/>
  </element>
 </xsl:template>
</xsl:stylesheet>
<root>
  <node>
  </node>
  <node>
    <node>
      <node>
      </node>
    </node>
  </node>
</root>
<root>
   <element/>
   <element>
      <element>
         <element/>
      </element>
   </element>
</root>
  • 仅对特定元素使用标识规则及其重写——这是最基本、最强大的XSLT设计模式

  • 如何使用1。以上我们实现了优雅而纯粹的“推式风格”转型


  • “什么样的”?这到底意味着什么?第二个示例不是有效的XML,因为有两个根元素。在一个有效的XML文档中只能有一个根元素。@Ignacio:我的意思是你能帮我写一个xslt,它可以使用示例XML吗@奥德:你说得对,我修正了。问得好,+1。请参阅我的答案,了解使用标识规则和纯推送样式的最“符合XSLT精神”的经典解决方案回答得好。您可能有兴趣了解身份规则设计模式——请参阅我的答案。我知道这是一个较旧的答案,但我很好奇:
    模板为什么指定
    节点()|@*
    作为
    的选择器?据我所知,一个直接的
    完成了同样的事情(因为标识模板已经指定了选择器)。@ABach:Identity规则的功能是不用修改就使用它——在这种特殊情况下,没有属性,但是明天有人可以更改XML文档的格式并添加一些属性。如果你坚持精确的身份规则,你就不必改变一个字符——所有的事情都会按预期的方式继续工作。啊,我明白了,我没想到在那个级别使用<代码> <代码>不会捕获子/孙子/等节点中的属性。谢谢你,迪米特里@阿巴克:不客气。您可以在此处阅读有关标识规则的更多信息: