1

在使用 XSLT 从给定 XML 的下方删除父节点时,我需要帮助。

<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="OpenProblems2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="OpenProblems2" Name="OpenProblems2">
   <Hello>
      <NewDataSet>
         <Table>
            <a>1832874</a>
            <b>HUME-9063</b>
            <c>not informed</c>
         </Table>
         <Table>
            <a>1832874</a>
            <b>HUME-9063</b>
            <c>not informed</c>
         </Table>
      </NewDataSet>
   </Hello>
</Report>

输出应该看起来像 -

<NewDataSet>
<Table>
  <a>1832874</a> 
  <b>HUME-9063</b> 
  <c>not informed</c>
</Table>
<Table>
  <a>1832874</a> 
  <b>HUME-9063</b> 
  <c>not informed</c>
</Table>
</NewDataSet>

XSLT 应该删除 Report、Hello 和 NewDataset 元素。请...您的帮助将不胜感激。

4

3 回答 3

1

如果你想保持命名空间不变,那么你只需要

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

    <xsl:template match="/">
        <xsl:copy-of select="o:NewDataSet"/>
    </xsl:template>

</xsl:stylesheet>
于 2013-10-29T14:58:20.817 回答
1

使用 XSLT 对 XML 文件进行小的更改的标准方法是定义一个身份模板,它将从输入到输出的所有内容原样复制,除非被更具体的模板覆盖:

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

然后提供特定的模板来匹配您想要更改的内容。在这种情况下,如果您知道总会有一个第三级元素(NewDataSet),那么您可以使用跳过前两级外包装元素

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

这两个模板一起会产生这样的输出

<NewDataSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="OpenProblems2">
<Table>
  <a>1832874</a> 
  <b>HUME-9063</b> 
  <c>not informed</c>
</Table>
<Table>
  <a>1832874</a> 
  <b>HUME-9063</b> 
  <c>not informed</c>
</Table>
</NewDataSet>

如果您还想删除所有命名空间,则需要添加第三个模板,如下所示:

<xsl:template match="*">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates select="@*|node()" />
  </xsl:element>
</xsl:template>

获取任何(或没有)命名空间中的任何元素,并将其替换为具有相同本地名称但不在命名空间中的新元素。

于 2013-10-29T11:24:32.453 回答
0

这种要求最好使用身份模板来处理。身份模板将允许您通过大部分未更改的 XML,然后只处理必要的部分。一个简单的身份如下所示:

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

这匹配所有属性、注释、元素等并将它们复制到输出。任何更具体的匹配将优先。

您的示例输出实际上并没有删除NewDataSet元素,所以我也没有。如果要删除它,请将其添加到下面的模板中(但请记住,它会使您的输出格式错误)

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

该模板匹配两个元素HelloReport通过简单地将模板应用到它们的子元素而不将实际节点复制到输出来处理它们。

因此,样式表如:

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

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

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

</xsl:stylesheet>

将获取您的样本输入并生成您的样本输出。正如@ian-roberts 指出的那样,如果你真的想去掉命名空间,你也需要处理它。

于 2013-10-29T11:27:06.660 回答