XML Key/value manipulation on condition using XSLT

那年仲夏 提交于 2019-12-11 10:13:58

问题


I have data like this -

<item>
    <name>Bob</name>
    <fav_food>pizza</fav_food>
    <key>Salary</key>
    <value />
    <value2>1000</value2>
    <value3 />
</item>

I want my output to look like this -

<item>
    <name>Bob</name>
    <fav_food>pizza</fav_food>
    <Salary>1000</Salary>
</item>

In this case, Salary gets the value of 1000 because value is empty and value2 is not (value has higher priority than value2, which has higher priority than value3).

It is guaranteed that value,value2 and value3 all exist, and only one of those is nonempty. Is it possible to use a XSLT transform to do this?

Currently, this is my transform.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />  

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

<xsl:template match="key">
    <xsl:element name="{substring-before(substring-after(.,'{'),'}')}"> 
        <xsl:choose>
            <xsl:when test="value != ''">
                <xsl:value-of select="following-sibling::value" />
            </xsl:when>
            <xsl:when test="value2 != ''">
                <xsl:value-of select="following-sibling::value2" />
            </xsl:when>
            <xsl:when test="value3 != ''">
                <xsl:value-of select="following-sibling::value3" />
            </xsl:when>
        </xsl:choose>
   </xsl:element> 
</xsl:template>
</xsl:stylesheet>

回答1:


I think you can simply do

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />  

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

<xsl:template match="key">
  <xsl:element name="{.}">
    <xsl:copy-of select="../(value, value2, value3)/text()"/>
  </xsl:element>
</xsl:template>

<xsl:template match="item/value | item/value2 | item/value3"/>

</xsl:stylesheet>

You might want or need to adjust the element name generation but I have not applied your name="{substring-before(substring-after(.,'{'),'}')}" as I don't see any braces in your input sample.



来源:https://stackoverflow.com/questions/17278477/xml-key-value-manipulation-on-condition-using-xslt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!