使用XSLT将XML节点组合成一个节点

时间:2018-11-07 20:48:48

标签: asp.net xml xslt

我正在尝试通过转换来编辑一些XML,但是我正在努力实现自己想要的结果。

我有一些XML:

<FX>
   <Order ATTRIBUTE1="ACTIVE" ATTRIBUTE2="CCY" />
   <Attribute NAME="N1" VALUE="V1" />
   <Attribute NAME="N2" VALUE="V2" />
   <Attribute NAME="N3" VALUE="V3" />
</FX>

我想将其转换为:

<FX>
   <Order ATTRIBUTE1="ACTIVE" ATTRIBUTE2="CCY" />
   <Attribute NAME="N1, N2, N3" VALUE="V1,V2,V3" />
</FX>

这可能吗?谁能提供任何有关如何使用转换的建议?

2 个答案:

答案 0 :(得分:1)

您可以使用以下与Asp.NET兼容的XSLT-1.0样式表来执行从源XML到目标XML的XSLT转换:

@Override
protected void onPostExecute(String s) {
    if(s == null) Log.e("InternetData", "Null was returned by the background task!");
    else Log.i("InternetData", s);
    super.onPostExecute(s);
}

其输出为:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/FX">
    <xsl:copy>
        <xsl:copy-of select="Order" />
        <Attribute>
            <xsl:attribute name="NAME">
                <xsl:for-each select="Attribute">
                    <xsl:value-of select="@NAME" />
                    <xsl:if test="position() != last()">
                        <xsl:text>, </xsl:text>
                    </xsl:if>
                </xsl:for-each>
            </xsl:attribute>
            <xsl:attribute name="VALUE">
                <xsl:for-each select="Attribute">
                    <xsl:value-of select="@VALUE" />
                    <xsl:if test="position() != last()">
                        <xsl:text>,</xsl:text>
                    </xsl:if>
                </xsl:for-each>
            </xsl:attribute>
        </Attribute>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

通常,如果要转换某些节点但保留其余节点,则可以使用身份转换模板作为起点,然后添加用于更改要更改的节点的模板:

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

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

  <xsl:template match="FX/Attribute[1]">
      <xsl:copy>
          <xsl:apply-templates select="@*"/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="FX/Attribute[position() > 1]"/>

  <xsl:template match="FX/Attribute[1]/@*">
      <xsl:attribute name="{name()}">
          <xsl:for-each select=". | ../following-sibling::Attribute/@*[name() = name(current())]">
              <xsl:if test="position() > 1">,</xsl:if>
              <xsl:value-of select="."/>
          </xsl:for-each>
      </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/jyH9rNk