Xml 如何使用XSL复制节点并更改其(原始和重复)嵌套子节点的值?
我刚刚开始使用XSL,需要有经验的人的帮助 我有一个包含大量内容的XML中的节点a。我想复制这个节点,通过其中嵌套标记的值来标识它 在创建与节点A相同的节点A'后,我想更改标识节点A的标记的值:节点A和节点A'。两个节点的新值将不同 以下是我的源XML:Xml 如何使用XSL复制节点并更改其(原始和重复)嵌套子节点的值?,xml,xslt,Xml,Xslt,我刚刚开始使用XSL,需要有经验的人的帮助 我有一个包含大量内容的XML中的节点a。我想复制这个节点,通过其中嵌套标记的值来标识它 在创建与节点A相同的节点A'后,我想更改标识节点A的标记的值:节点A和节点A'。两个节点的新值将不同 以下是我的源XML: <businessFields> <businessField> <businessFieldID> <namespace>
<businessFields>
<businessField>
<businessFieldID>
<namespace>
<name>foo</name>
</namespace>
<name>foobar</name>
</businessFieldID>
<datatype>java.lang.Boolean</datatype>
<value>false</value>
</businessField>
<businessField>
<businessFieldID>
<namespace>
<name>bar</name>
</namespace>
<name>foobar3</name>
</businessFieldID>
<datatype>java.lang.String</datatype>
<value>No</value>
</businessField>
<!-- some more businessField nodes-->
</businessFields>
福
福巴
java.lang.Boolean
错误的
酒吧
foobar3
java.lang.String
不
我需要在/businessFields/businessField/businessFieldID/name标记中使用foobar值复制节点,并希望更改这两个节点的值
我的XSL如下所示:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//businessField[businessFieldID/name='foobar']">
<xsl:copy-of select="."/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//businessField[businessFieldID/name='foobar']/businessFieldID/name/text()">
<xsl:value-of select="'foobar1'"/>
</xsl:template>
</xsl:stylesheet>
因此,基本上我可以复制我感兴趣的节点,并更改所需名称标记的值,但仅限于其中一个节点
以下是期望的输出:
<?xml version="1.0" encoding="UTF-8"?>
<businessFields>
<businessField>
<businessFieldID>
<namespace>
<name>foo</name>
</namespace>
<name>foobar1</name>
</businessFieldID>
<datatype>java.lang.Boolean</datatype>
<value>false</value>
</businessField>
<businessField>
<businessFieldID>
<namespace>
<name>foo</name>
</namespace>
<name>foobar2</name>
</businessFieldID>
<datatype>java.lang.Boolean</datatype>
<value>false</value>
</businessField>
<businessField>
<businessFieldID>
<namespace>
<name>bar</name>
</namespace>
<name>foobar3</name>
</businessFieldID>
<datatype>java.lang.String</datatype>
<value>No</value>
</businessField>
</businessFields>
福
foobar1
java.lang.Boolean
错误的
福
foobar2
java.lang.Boolean
错误的
酒吧
foobar3
java.lang.String
不
我尝试使用
迭代所有以foobar作为值的节点,并根据位置()更改值,但我弄错了一些东西,它只是将所有节点的名称更改为相同的名称
这是我关于stackoverflow的第一个问题,英语不是我的母语,如果不清楚,很抱歉。请让我知道我能做些什么来改进我的问题,并感谢您的帮助。如果我理解正确(这一点不确定),您想做:
XSLT1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="businessField[businessFieldID/name='foobar']">
<!-- original -->
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<!-- duplicate -->
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="duplicate"/>
</xsl:copy>
</xsl:template>
<!-- identity transform for duplicates -->
<xsl:template match="@*|node()" mode="duplicate">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="duplicate"/>
</xsl:copy>
</xsl:template>
<!-- modify original -->
<xsl:template match="businessField[businessFieldID/name='foobar']/businessFieldID/name/text()">
<xsl:text>foobar1</xsl:text>
</xsl:template>
<!-- modify duplicate -->
<xsl:template match="businessField[businessFieldID/name='foobar']/businessFieldID/name/text()" mode="duplicate">
<xsl:text>foobar2</xsl:text>
</xsl:template>
</xsl:stylesheet>
foobar1
foobar2
2021年的撒克逊对我来说听起来像XSLT 3,所以也许
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="name-to-check" as="xs:string">foobar</xsl:param>
<xsl:param name="new-value" as="xs:string">foobar</xsl:param>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="businessField[businessFieldID/name = $name-to-check]">
<xsl:copy>
<xsl:apply-templates>
<xsl:with-param name="suffix" tunnel="yes" select="1"/>
</xsl:apply-templates>
</xsl:copy>
<xsl:copy>
<xsl:apply-templates>
<xsl:with-param name="suffix" tunnel="yes" select="2"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="businessField/businessFieldID/name[. = $name-to-check]/text()">
<xsl:param name="suffix" tunnel="yes"/>
<xsl:value-of select="$new-value || $suffix"/>
</xsl:template>
</xsl:stylesheet>
福巴
福巴
够了,甚至
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="name-to-check" as="xs:string">foobar</xsl:param>
<xsl:param name="new-value" as="xs:string">foobar</xsl:param>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="businessField[businessFieldID/name = $name-to-check]">
<xsl:apply-templates select="., ." mode="change"/>
</xsl:template>
<xsl:template match="businessField" mode="change">
<xsl:copy>
<xsl:apply-templates mode="#default">
<xsl:with-param name="suffix" tunnel="yes" select="position()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="businessField/businessFieldID/name[. = $name-to-check]/text()">
<xsl:param name="suffix" tunnel="yes"/>
<xsl:value-of select="$new-value || $suffix"/>
</xsl:template>
</xsl:stylesheet>
福巴
福巴
您使用哪个版本的XSLT,哪个XSLT处理器?制作businessField[businessFieldID/name='foobar']
的深度副本,并将其推送到模板中,或者在与businessField[businessFieldID/name='foobar']
@MartinHonnen匹配的模板中使用
两次,因为它是1.0版和萨克森处理器。至于你的建议,我想我已经在做你刚才描述的事情了。除非我遗漏了什么。@PawełRuta您是在Saxon中使用XSLT1.0吗?为什么?它工作得很好mode=“duplicate”
是我丢失的部分。谢谢你,伙计!