xml - 如何使用 XSL 复制节点并更改其(原始和重复的)嵌套子节点的值?
问题描述
我刚开始使用 XSL,我需要有经验的人的帮助。
我在一个包含很多内容的 XML 中有一个节点 A。我想复制这个节点,通过它里面的嵌套标签的值来识别它。
创建与节点 AI 相同的节点 A' 后,想要更改我为节点 A 标识的标签的值:节点 A 和节点 A'。两个节点的新值将不同。
这是我的源 XML:
<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>
我需要在/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>
我尝试使用<xsl:for-each>
迭代所有以foobar作为值的节点并根据值更改值,position()
但我搞砸了一些东西,它只是将它更改为所有节点的相同名称。
这是我关于 stackoverflow 的第一个问题,英语不是我的母语,如果不清楚,请见谅。请让我知道我该怎么做才能使我的问题变得更好,并感谢您的帮助。
解决方案
如果我理解正确(这完全不确定),你想做:
XSLT 1.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>
推荐阅读
- javascript - 计算一个元素在多个其他数组 JavaScript 中的出现次数
- powershell - PowerShell Cmdlet 开发:关于在 Cmdlet 之间通过管道传输的 IEnumerable 的最佳实践
- html - 在不使用absolute或flex的情况下将div定位到父级的右下角
- alpha-vantage - 全球报价中的 Alpha Vantage 货币
- android - 构建错误,NuGet 引用包错误
- angular - TypeScript:如何拥有默认泛型?
- html - 如何在我的网格列中居中我的网格项目?
- c# - 为什么 TCP 连接在 HoloLens 模拟器(第一代)中不起作用?
- reactjs - 在构建 Docker 映像时要求安装 Typescript
- emacs - 将 chezschme 设置为 geiser-default-implementation