【问题标题】:XSLT: Nested/move a node and its children into a new nodeXSLT:将节点及其子节点嵌套/移动到新节点中
【发布时间】:2021-09-05 09:54:33
【问题描述】:

我想用 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 节点及其子节点嵌套到一个新节点中。但只有具有 name="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>

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    您的模板匹配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>
    

    【讨论】:

    • 谢谢!这是解决方案:-)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多