当前位置: 首页 > 知识库问答 >
问题:

XSLT:嵌套/将节点及其子节点移动到新节点中

施玉宸
2023-03-14

我想用XSLT转换XML文档。按名称和属性匹配的节点及其子节点应嵌套/移动到新节点中。

从转变

<v:data name="Custom">
    <valueA>bla</valueA>
    <valueB>bla</valueB>
    <valueC>
        <valueA>bla</valueA>
        <valueB>bla</valueB>        
    </valueC>
</v:data>

<v:container type="static">
    <!-- origin node -->
    <v:data name="Custom">
        <valueA>bla</valueA>
        <valueB>bla</valueB>
        <valueC>
            <valueA>bla</valueA>
            <valueB>bla</valueB>        
        </valueC>
    </v:data>
</v:container>

但是我的XSLT工作不好。您有什么提示吗,XSLT文件有什么问题?

非常感谢你

安德烈亚斯

我的XSLT

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:v="http://acme.com/schema.xsd" 
xmlns:d="http://acme.com/data.xsd" 
>

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="v:data/@name[.='Custom']"> 
    <xsl:element name="v:container">
        <xsl:attribute name="type">static</xsl:attribute>
            <xsl:copy>
                <xsl:apply-templates select="@*|node()" />
            </xsl:copy>
    </xsl:element> 
</xsl:template>

</xsl:stylesheet>

输出:

<?xml version="1.0" encoding="UTF-8"?>
<datamodel xmlns:v="http://acme.com/schema.xsd" xmlns:d="http://acme.com/data.xsd">

<v:data> <!-- should be under v:container -->
  <v:container type="static" name="Custom"/> <!-- attribute name should be by v:data -->
  <valueA>bla</valueA> <!-- children should be under v:data -->
  <valueB>bla</valueB>
  <valueC>
    <valueA>bla</valueA>
    <valueB>bla</valueB>
  </valueC>
</v:data>

<v:data name="Default"> <!-- okay: is untouched -->
  <valueA>bla</valueA>
  <valueB>bla</valueB>
  <valueC>
    <valueA>bla</valueA>
    <valueB>bla</valueB>
  </valueC>
</v:data>
</datamodel>

我的源XML文件

<?xml version="1.0" encoding="UTF-8"?>
<datamodel 
 xmlns:v="http://acme.com/schema.xsd" 
 xmlns:d="http://acme.com/data.xsd" 
>

<v:data name="Custom">
    <valueA>bla</valueA>
    <valueB>bla</valueB>
    <valueC>
        <valueA>bla</valueA>
        <valueB>bla</valueB>        
    </valueC>
</v:data>

<v:data name="Default">
    <valueA>bla</valueA>
    <valueB>bla</valueB>
    <valueC>
        <valueA>bla</valueA>
        <valueB>bla</valueB>        
    </valueC>    
</v:data>

</datamodel>

我希望在转换后的输出中将v:data节点及其子节点嵌套到一个新节点中。但只有属性名为“Custon”的v:data节点。转换后的XML文档应该如下所示

<?xml version="1.0" encoding="UTF-8"?>
<datamodel 
 xmlns:v="http://acme.com/schema.xsd" 
 xmlns:d="http://acme.com/data.xsd" 
>

<v:container type="static"> <!-- changed -->
    <v:data name="Custom">
        <valueA>bla</valueA>
        <valueB>bla</valueB>
        <valueC>
            <valueA>bla</valueA>
            <valueB>bla</valueB>        
        </valueC>
    </v:data>
</v:container>

<v:data name="Default"> <!-- unchanged -->
    <valueA>bla</valueA>
    <valueB>bla</valueB>
    <valueC>
        <valueA>bla</valueA>
        <valueB>bla</valueB>        
    </valueC>    
</v:data>

</datamodel>

如果我从XSLT中的模板中删除属性选择器,则匹配不带属性。这将是可行的,但现在每个节点都被转换了。

<?xml version="1.0" encoding="UTF-8"?>
<datamodel xmlns:v="http://acme.com/schema.xsd" xmlns:d="http://acme.com/data.xsd">
  
  <v:container type="static"> <!-- as I expected -->
    <v:data name="Custom">
      <valueA>bla</valueA>
      <valueB>bla</valueB>
      <valueC>
        <valueA>bla</valueA>
        <valueB>bla</valueB>
      </valueC>
    </v:data>
  </v:container>

  <v:container type="static"> <!-- but all v:data nodes are moved -->
    <v:data name="Default">
      <valueA>bla</valueA>
      <valueB>bla</valueB>
      <valueC>
        <valueA>bla</valueA>
        <valueB>bla</valueB>
      </valueC>
    </v:data>
  </v:container>
</datamodel>

共有1个答案

华季萌
2023-03-14

您的模板匹配name属性而不是v: data元素。这样试试:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:v="http://acme.com/schema.xsd" 
xmlns:d="http://acme.com/data.xsd" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="v:data[@name='Custom']">
    <v:container type="static">
        <xsl:copy-of select="."/>
    </v:container>
</xsl:template>

</xsl:stylesheet>
 类似资料:
  • 我想从XML结构中使用单个节点创建嵌套的XML节点,我尝试过但无法带来嵌套的XML结构,请一些人帮助我,我无法获得预期的行为。 XML结构: XSL使用: 收到的输出: 预期产出 “人员非活动”元素应用于匹配

  • 我需要以下xslt代码方面的帮助。我的意见如下: 我的预期输出为: 我曾尝试使用*/text()获取值节点的值,但我只从第一个孩子获得文本。将来我有很多这样的子元素。 提前谢谢。 你好,Minakshi

  • 我想从父节点复制到子节点。我真的不确定这是如何实现的。 我的源xml 我想得到输出为 我想要XSLT1.0中的解决方案。 我想将这些节点复制到子节点 谢谢。

  • 问题内容: 我需要一个MySQL查询,该查询可在一个嵌套集中移动一个节点及其所有子节点。我找到了这个站点,但是该函数似乎非常不合逻辑- 没有或没有嵌套的集合模型,并且代码本身仅比所需的更长。我在表格中仅有的额外一列是。 我不能只删除并再次添加该节点,因为它将丢失其ID。 问题答案: 我知道,这个主题已经很老了,但是无论如何仍然没有答案。我是从Google来到这里的,没有找到这个问题的直接答案。 因

  • 我需要将子元素复制到父元素中。 输入 期望输出 我尝试的内容(输出与输入保持相同): 我肯定会错过一些非常简单的事情。子元素与父元素具有相同的名称,这应该不是问题?

  • 问题内容: 我正在一个项目中,用户对我们的代客服务的请求在另一端代客接受请求。 我正在使用Firebase作为后端,并应要求将客户uid保存在“ request”子项上。 当代客接受请求时,客户uid应从“请求”节点移至“进行中”节点。 我怎样才能做到这一点? 问题答案: 我建议使用这个: 这来自以下来源:https : //gist.github.com/katowulf/6099042。我在J