Xml 如何将子节点转换为当前节点的属性

Xml 如何将子节点转换为当前节点的属性,xml,xslt,Xml,Xslt,我在这里发现了一个类似的问题: 但这不正是我需要的。假设在这里使用相同的示例: <A> <b attr1="xx"> <c> Turn this into an Attribute </c> </b> </A> 将其转换为属性 我希望xslt之后生成的xml如下所示: <A> <b attr1="xx" cAttr="Turn this into an Attrib

我在这里发现了一个类似的问题:

但这不正是我需要的。假设在这里使用相同的示例:

<A>
 <b attr1="xx">
   <c>
    Turn this into an Attribute  
   </c>
 </b>
</A>

将其转换为属性
我希望xslt之后生成的xml如下所示:

 <A>
  <b attr1="xx" cAttr="Turn this into an Attribute">
  </b>
 </A>

使用我目前的知识,我只能设法摆脱节点或将其名称更改为所需的名称“cAttr”,但我真的不知道如何将整个节点转化为父节点的属性,只知道如何引用父节点的属性字段在这里对我帮助不大

我当前的代码如下所示:

<xsl:template match="c">
 <xsl:element name="cAttr">
    <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>
<A>
    <b attr1="xx">
        <d>SomeNode</d>
        <c>
            Turn this into an Attribute
        </c>
        <f>SomeMoreNode</f>
    </b>
</A>

提前感谢。


<!-- match b node -->
<xsl:template match="b">
  <!-- apply templates on all attributes and nodes. see two templates below -->
  <xsl:apply-templates select="@*|node()"/>
</xsl:template>

<!-- copy all existing attrs -->
<xsl:template match="b/@*">
  <xsl:copy-of select="."/>
</xsl:template>

<!-- populate attributes from nodes -->
<xsl:template match="b/node()">
  <xsl:attribute name="{name()}Attr"> <!-- attribute name -->
    <xsl:value-of select="text()"/> <!-- attribute value -->
  </xsl:attribute>
  <!-- match all attributes on child node -->
  <xsl:apply-templates select="@*">
    <xsl:with-param name="prefix" select="name()"/> <!-- pass node name to template -->
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="b/node()/@*">
  <xsl:param name="prefix"/>
  <!-- creates attribute prefixed with child node name -->
  <xsl:attribute name="{$prefix}-{name()}">
    <xsl:value-of select="."/>
  </xsl:attribute>
</xsl:template>

不如Gleb的版本好,但如果我已经浪费了时间,为什么不发布呢=;)


不如Gleb的版本好,但如果我已经浪费了时间,为什么不发布呢=;)


我更喜欢更简洁(尽管可能不太通用)的设计:


应用于XML,如下所示:

<xsl:template match="c">
 <xsl:element name="cAttr">
    <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>
<A>
    <b attr1="xx">
        <d>SomeNode</d>
        <c>
            Turn this into an Attribute
        </c>
        <f>SomeMoreNode</f>
    </b>
</A>

某物节点
将其转换为属性
萨默诺德
结果将是:

<A>
    <b attr1="xx" cAttr="Turn this into an Attribute">
        <d>SomeNode</d>
        <f>SomeMoreNode</f>
    </b>
</A>

某物节点
萨默诺德
我更喜欢更简洁(尽管可能不太通用)的设计:


应用于XML,如下所示:

<xsl:template match="c">
 <xsl:element name="cAttr">
    <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>
<A>
    <b attr1="xx">
        <d>SomeNode</d>
        <c>
            Turn this into an Attribute
        </c>
        <f>SomeMoreNode</f>
    </b>
</A>

某物节点
将其转换为属性
萨默诺德
结果将是:

<A>
    <b attr1="xx" cAttr="Turn this into an Attribute">
        <d>SomeNode</d>
        <f>SomeMoreNode</f>
    </b>
</A>

某物节点
萨默诺德

除了@Flack正确的推送方式外,为了好玩,还有两种推送方式:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="b/*[1][self::c]" name="attribute" priority="1">
        <xsl:attribute name="cAttr">
            <xsl:value-of select="../c"/>
        </xsl:attribute>
    </xsl:template>
    <xsl:template match="b[c]/*[1]">
        <xsl:call-template name="attribute"/>
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="b/c"/>
</xsl:stylesheet>

编辑:哎呀!我错过了剥离规则。

除了@Flack正确的推送方式,为了好玩,还有两种拉式方法:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="b/*[1][self::c]" name="attribute" priority="1">
        <xsl:attribute name="cAttr">
            <xsl:value-of select="../c"/>
        </xsl:attribute>
    </xsl:template>
    <xsl:template match="b[c]/*[1]">
        <xsl:call-template name="attribute"/>
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="b/c"/>
</xsl:stylesheet>

编辑:哎呀!我错过了脱衣规则。

是的,就像我说的,这不太好。它只适用于这种特殊情况。说到XSL,我还是一名新生|是的,就像我说的,不太好。它只适用于这种特殊情况。说到XSL,我还是一名新生|
b/node()
不会也尝试将子元素的属性转换为“b”的属性吗?只是想在这里学习一下。
b/node()
不会也尝试将子元素的属性转换为“b”的属性吗?这是一个更好、语义更正确的答案,此外,我会将模板应用于
c
,以防没有模板。或者在
b
模式中使用过滤器,如
b[c]
+1这是一个更好、语义更正确的答案,此外,我会将模板应用于
c
,以防没有模板。或者在
b
模式中使用过滤器,如
b[c]