按名称将孩子合并为未知的父母

时间:2019-04-04 20:01:40

标签: xml xslt

我正在尝试将Child元素合并到其Parent,将所有属性从Child移到Parent,然后向后移走Child。

喜欢这个:

<?xml version="1.0" encoding="utf-8" ?>
<Blocks>
  <Block ID="OA00" Name="Generic">
    <Design ID="DA00" />
  </Block>
  <Block ID="OA01" Name="WildStar" DenyChange="true">
    <Design ID="DA00" />
    <Coordinate X="50" Y="60" />
  </Block>
  <Block ID="OA02" Name="Eraser" />
</Blocks>

进入此:

<?xml version="1.0" encoding="utf-8" ?>
    <Blocks>
      <Block ID="OA00" Name="Generic">
        <Design ID="DA00" />
      </Block>
      <Block ID="OA01" Name="WildStar" DenyChange="true" X="50" Y="60" >
        <Design ID="DA00" />
      </Block>
      <Block ID="OA02" Name="Eraser" />
    </Blocks>

但是,父母的名字并不总是“ Block”,而是孩子的名字总是“ Coordinate”。

这用于序列化和反序列化vb.net类,其中Coordinate是该类内部的结构。

This one was the closest i came to what i wanted,但不能解决未知的父级名称。

这是我现在拥有的,但是我是XSLT的新手:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" 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()">
    <xsl:variable name="name" select="name(..)" />
    <xsl:if test="*[local-name() = 'Coordinate']">
        <xsl:element name="{$name}">
        <xsl:copy-of select="@*|Coordinate/@*" />
        <xsl:apply-templates />
        </xsl:element>
    </xsl:if>
    </xsl:template>

    <xsl:template match="Coordinate"/>

</xsl:stylesheet>

我希望“ if”测试可以确保仅将Coordinate属性复制到Parent,但是在i try to run it through here.时我得到的是空白输出

总而言之,如果节点的子节点名称为“坐标”,则该节点中的所有内容均应移至其父节点,然后删除“坐标”节点。

2 个答案:

答案 0 :(得分:1)

您需要的是一个模板,该模板与任何以Coordinate作为子元素的元素相匹配...

<xsl:template match="*[Coordinate]">

然后,您可以复制该元素,并添加坐标属性。

尝试使用此XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*" />

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

    <xsl:template match="*[Coordinate]">
        <xsl:copy>
            <xsl:copy-of select="@*|Coordinate/@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Coordinate"/>
</xsl:stylesheet>

请注意,在原始XSLT中,有两个模板与同一事物匹配(在这种情况下为node()),这被认为是错误。处理器可以标记错误,或者选择最后一个匹配的模板

答案 1 :(得分:1)

只是为了好玩,此样式表对标识规则进行了少量修改,而另一个空规则用于丢弃Coordinate元素:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|Coordinate/@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Coordinate"/>
</xsl:stylesheet>

输出:

<Blocks>
  <Block ID="OA00" Name="Generic">
    <Design ID="DA00"/>
  </Block>
  <Block ID="OA01" Name="WildStar" DenyChange="true" X="50" Y="60">
    <Design ID="DA00"/>    
  </Block>
  <Block ID="OA02" Name="Eraser"/>
</Blocks>