将属性转换为元素

时间:2019-04-30 17:50:37

标签: xml xslt

我讨厌写XSLT,主要是因为我不擅长。我有一个XML数据文件,其中的所有内容都是属性,而不是有意义的节点内的直接值。

我想运行一个XSLT转换,它可以解决这个问题:

<token-value-entry token-name="RECIPIENT_CITY">
<token-value><value>ROSEBURG</value></token-value>
</token-value-entry>
<token-value-entry token-name="RECIPIENT_STATE">
<token-value><value>OR</value></token-value>
</token-value-entry>

对此:

<RECIPIENT_CITY>ROSEBURG</<RECIPIENT_CITY>
<RECIPIENT_STATE>OR</RECIPIENT_STATE>

好,再修改一次。什么时候让stackoverflow变得有些古怪?

特定问题:是否可以使用属性的值作为新元素的名称?

我有这个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:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

  <xsl:template match="@token-name">
    <xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element>
  </xsl:template>
</xsl:stylesheet>

哪个产生以下输出:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <token-value-entry>
        <token-name>RECIPIENT_CITY</token-name>
        <token-value>
            <value>ROSEBURG</value>
        </token-value>
    </token-value-entry>
    <token-value-entry>
        <token-name>RECIPIENT_STATE</token-name>
        <token-value>
            <value>OR</value>
        </token-value>
    </token-value-entry>
</root>

除了“保持谷歌搜索”之外,我想回答的问题是,我要使用什么而不是{name()}变量来输出值“ RECIPIENT_CITY”作为节点的名称?

就目前而言,如果我能得到这个输出,我很可能就能弄清楚其余的东西:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <token-value-entry>
        <RECIPIENT_CITY />
        <token-value>
            <value>ROSEBURG</value>
        </token-value>
    </token-value-entry>
    <token-value-entry>
        <RECIPIENT_STATE />
        <token-value>
            <value>OR</value>
        </token-value>
    </token-value-entry>
</root>

提出另一种方法,如何将属性的值存储在变量中,以便在其他地方使用该变量来创建元素?

4 个答案:

答案 0 :(得分:1)

更改

  <xsl:template match="@token-name">
    <xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element>
  </xsl:template>

  <xsl:template match="token-value-entry">
    <xsl:element name="{@token-name}"><xsl:value-of select="."/></xsl:element>
  </xsl:template>

答案 1 :(得分:0)

如果您处于以下情况:

<xsl:for-each select="token-value-entry">

或:

<xsl:template match="token-value-entry">

然后说明:

<xsl:element name="{@token-name}">
    <!-- content here --> 
</xsl:element>

将创建所需的元素(只要token-name属性包含有效的XML元素名称)。

要了解其工作原理,请阅读:https://www.w3.org/TR/1999/REC-xslt-19991116#attribute-value-templates

答案 2 :(得分:0)

由于您提出了一些有关如何解决该问题的元问题,所以让我尝试解决这些问题。

我认为您的语言学习方法有问题。答案当然不是“继续使用谷歌搜索”:相反,我认为您一直在尝试通过谷歌搜索来解决问题,而无需坐下来系统地研究语言的概念。

这就是为什么您对此过程感到沮丧的原因。

您的问题“有没有一种方法可以将属性值用作新元素的名称?”说明了这一点。如果您知道如何使用@xxx来获取属性的值,并且如果您知道如何使用xsl:element来构造元素,那么将这两个想法组合在一起就不会有麻烦。

如果您使用google并对其进行描述,则只有在有人完全解决了相同的问题并用相同的术语描述了问题的情况下,它才会找到答案。其他人可能已经解决了一个稍微不同的问题,即需要完全相同的原语来解决它,或者他们可能用不同的术语来描述它,而您将找不到信息。而且,如果您确实找到了答案,则可能会以您尚未掌握的概念和术语来进行描述,因为您的所有知识都是随机抽取的,其中有些是由实际上能力很少的人撰写的。 / p>

从一开始就开始学习示例,并为自己获取一本关于该语言的好书并阅读。作者将注意主题的显示顺序,以便每一章都以您在前几章中学到的知识为基础。它将教您可以使用的构建基块,并为您提供示例,说明如何将它们组合起来以解决问题,其中一些类似于您自己的问题,有些非常不同。

这里所需的构建块非常简单,您已经在使用它们,但是在我看来,您似乎在使用它们时并没有真正理解它们。我怀疑您复制了通过谷歌搜索找到的代码,但实际上并没有理解。那不是正确的策略。

答案 3 :(得分:0)

这里有很多假设。也许我不想学习这种语言,但是正在尝试在同事缺席的情况下解决一个孤立的问题?也许我只是一名顾问,只是想尝试进行概念验证,而“真正的编码员”会很忙吗?也许我15年前学习过XML / 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:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="token-value-entry">
      <xsl:element name="{@token-name}">
        <xsl:apply-templates />
      </xsl:element>
    </xsl:template>

</xsl:stylesheet>

源XML具有多个<token-value-entry token-name="xxx"><token-value><value>My Value</value></token-value></token-value-entry>构造,其中一些嵌套在其他<token-value-entry>父节点中。

<token-value-entry token-name="RECIPIENT_STATE">
                    <token-value>
                        <value>OR</value>
                    </token-value>
                </token-value-entry>
                <token-value-entry token-name="CNSMR_ACCNTS">
                    <token-value>
                        <list-of-values>
                            <token-value-entry token-name="ACCNT_CURBAL">
                                <token-value>
                                    <value>.73</value>
                                </token-value>

我的目标是打开以下每个实例:

<token-value-entry token-name="SOME_VALUE">...</token-value-entry>

进入:

<SOME_VALUE>...</SOME_VALUE>

发表评论并提供链接的人们使我克服了概念上的障碍。我需要重新学习的部分是如何在xsl中使用变量,现在要选择整个节点,而不仅仅是文本值。谢谢。