循环遍历节点并使用 XSLT 将值附加到字符串
Posted
技术标签:
【中文标题】循环遍历节点并使用 XSLT 将值附加到字符串【英文标题】:Loop through nodes and append value to a string using XSLT 【发布时间】:2016-07-18 05:32:00 【问题描述】:我有以下 XML。在根节点下,我有保存配置的“搜索”节点和有请求的“请求”节点。在“Req”节点内有一个“classId”节点。我正在存储我在这里有一个复杂问题的值。我的最终结果中有一个“appendString”节点。首先,我需要检查“Req”节点内的子节点是否具有值。如果它有值,我需要获取节点名称并匹配 AllClass/class1/node3 中的节点并获取它的值,最后我需要在 'appendString' 节点内形成一个字符串,如下所示 'Childname1=value1,Childname2=值2'。请帮忙。谢谢
我的 XML
<root>
<ns:Search xmlns:ns="http://example.com/1.0/">
<ns:AllClass>
<ns:class1>
<ns:node1>fhgfjh</ns:node1>
<ns:node2>Aprtyrtyril</ns:node2>
<ns:node3>
<ns:firstChild>Childname1</ns:firstChild>
<ns:SecondChild>Childname2</ns:SecondChild>
</ns:node3>
</ns:class1>
<ns:class2>
<ns:node1>dfgd</ns:node1>
<ns:node2>trytyu</ns:node2>
<ns:node3>
<ns:firstChild>Childname11</ns:firstChild>
<ns:SecondChild>Childname22</ns:SecondChild>
<ns:ThirdChild>Childname33</ns:ThirdChild>
</ns:node3>
</ns:class2>
.
.
.
.
.
.
</ns:AllClass>
</ns:Search>
<ns:Req xmlns:ns="http://example.com/1.0/">
<ns:classId>class1</ns:classId>
<ns:className>asdfg</ns:className>
<ns:firstChild>value1</ns:firstChild>
<ns:SecondChild>value2</ns:SecondChild>
<ns:ThirdChild></ns:ThirdChild>
<ns:FourthChild></ns:FourthChild>
.
.
.
.
.
</ns:Req>
</root>
XSL
<xsl:template match="root/Req">
<xsl:variable xmlns:ns="http://example.com/1.0/" name="class_tmp" select="/root/ns:Req/ns:classId" />
<xsl:variable name="class" select="concat('ns:',$class_tmp)" />
<ns1:Response xmlns:ns1="http://example.com/ns/">
<ns1:SearchString>
<xsl:value-of xmlns:ns="http://example.com/1.0/" xmlns:ns1="http://example.com/1.0/" select="/root/ns:Search/ns:AllClassM/*[name()=$class]/ns:node2" />
</ns1:SearchString>
<xsl:apply-templates/>
</ns1:Response>
</xsl:template>
<xsl:template match="root/Req/*">
<ns1:appendString></ns1:appendString>
</xsl:template>
最终的 XML
<ns1:Response xmlns:ns1="http://example.com/ns/">
<ns1:SearchString>Aprtyrtyril</ns1:SearchString>
<ns1:appendString>Childname1=value1,Childname2=value2</ns1:appendString>
</ns1:Response>
【问题讨论】:
附加您的示例预期结果 XML @nawazlj 添加了示例 XML 【参考方案1】:--- 根据澄清进行了编辑---
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://example.com/1.0/"
xmlns:ns1="http://example.com/ns/"
exclude-result-prefixes="ns">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="id" match="ns:AllClass/*" use="name()" />
<xsl:key name="label" match="ns:node3/*" use="concat(name(), '|', name(../..))" />
<xsl:template match="/root">
<xsl:variable name="classId" select="concat('ns:', ns:Req/ns:classId)" />
<ns1:Response>
<ns1:SearchString>
<xsl:value-of select="key('id', $classId)/ns:node2" />
</ns1:SearchString>
<ns1:appendString>
<xsl:for-each select="ns:Req/*[not(self::ns:classId or self::ns:className)][text()]">
<xsl:value-of select="key('label', concat(name(), '|', $classId))" />
<xsl:text>=</xsl:text>
<xsl:value-of select="." />
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</ns1:appendString>
</ns1:Response>
</xsl:template>
</xsl:stylesheet>
这假定除了ns:classId
和ns:className
之外的ns:Req
下的任何节点都是“子节点”,如果不为空则需要列出。
【讨论】:
谢谢,我会检查 它工作正常,我使用的是第二种方式。但我想要它有点不同。我想获取我在“appendString
从ns:classId
中指定的节点的node3 中获取“标签”(Childname1、Childname2)?但我不知道您所说的“firstChild 或 secondChild 中的值对于不同的类可能不同,并且即使 'Req' 中的所有节点都有值,'appendString' 也应该只包含存在于 'node3' 中的节点在里面”。
示例 1.if classId = class1 then appendString => Childname1=value1,Childname2=value2 2. if classId = class2 then appendString => Childname11=value1,Childname22=value2,Childname33=value3 我已经更新XML
我想要在 node3 之前的 classId,所以应该是 Michael 之前建议的相反方向,下面是工作的 XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://example.com/1.0/"
xmlns:ns1="http://example.com/ns/"
exclude-result-prefixes="ns">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="id" match="ns:AllClass/*" use="name()" />
<xsl:key name="req" match="ns:Req/*" use="name()" />
<xsl:template match="root">
<xsl:variable name="classId" select="concat('ns:', ns:Req/ns:classId)" />
<ns1:Response>
<ns1:SearchString>
<xsl:value-of select="key('id', $classId)/ns:node2" />
</ns1:SearchString>
<ns1:appendString>
<xsl:for-each select="key('id', $classId)/ns:node3/*">
<xsl:value-of select="." />
<xsl:text>=</xsl:text>
<xsl:value-of select="key('req',name())" />
<xsl:if test="position()!=last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</ns1:appendString>
</ns1:Response>
</xsl:template>
</xsl:stylesheet>
【讨论】:
以上是关于循环遍历节点并使用 XSLT 将值附加到字符串的主要内容,如果未能解决你的问题,请参考以下文章