【问题标题】:XSL copy then replace attributesXSL 复制然后替换属性
【发布时间】:2017-01-27 11:16:32
【问题描述】:

INPUT.xml

 <human gender="male" nationality="american">
    <property>blank</property>
 </human>

(所需)OUTPUT.xml

 <human gender="male" nationality="american">
    <property>blank</property>
 </human>
 <person gender="female" nationality="british">
    <property>blank</property>
 </person>

大家好,以上是我想要的转换。 到目前为止,我有以下 xsl:

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

但是我如何去替换属性值 我尝试使用 xsl:choose 但没有运气

【问题讨论】:

  • 您想要的输出文档不是格式良好的 XML 文档,我建议您 a) 生成具有单个最外层元素的文档(其中包含其他所有元素)或 b) 不命名它*.xml。另外,请展示一个完整的、最小的 XSLT 样式表。谢谢。更多帮助:stackoverflow.com/help/mcve.

标签: xml xslt xslt-1.0


【解决方案1】:

您的样式表很接近,它只是缺少与您的其他模板不匹配的那些节点匹配的模板,因此它们不会被built-in templates of XSLT 拾取。

对于属性的转换我选择了引入模式,这样一些模板只匹配第二种你想改变属性值的情况。

以下样式表

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

<xsl:template match="human">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    <person>
        <!-- mode is used to separate this case from the other where things are copied unchanged -->
        <xsl:apply-templates select="node()|@*" mode="other" />
    </person>   
</xsl:template>

<!-- templates for normal mode -->

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

<!-- templates for "other" mode -->

<xsl:template match="@gender" mode="other">
    <xsl:attribute name="gender">
        <xsl:if test=". = 'male'">female</xsl:if>
        <xsl:if test=". = 'female'">male</xsl:if>
    </xsl:attribute>
</xsl:template>

<xsl:template match="@nationality" mode="other">
    <xsl:attribute name="nationality">
        <xsl:if test=". = 'american'">british</xsl:if>
        <xsl:if test=". = 'british'">american</xsl:if>
    </xsl:attribute>
</xsl:template>

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

</xsl:stylesheet>

应用于此输入时:

<human gender="male" nationality="american">
    <property>blank</property>
</human>

给出以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<human gender="male" nationality="american">
    <property>blank</property>
</human>
<person gender="female" nationality="british">
    <property>blank</property>
</person>

【讨论】:

  • 请不要过早回答,这可能会妨碍提问者编辑和改进他们的问题。您的输出不太正确,其中一种性别应该是“女性”并且应该是“英国人”。
  • 感谢回复。不幸的是,我确实有一个将美国男人变成英国女士的用例....
  • 我更新了我的答案以反映这一点。第一个版本只是说明了原始样式表的明显不完整。很抱歉。
猜你喜欢
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
  • 2015-07-26
  • 2015-02-20
  • 1970-01-01
  • 2020-02-06
相关资源
最近更新 更多