循环遍历节点并使用XSLT将值附加到字符串

时间:2016-07-18 05:32:01

标签: xml xslt xpath

我有以下XML。在根节点下,我有'搜索'节点,其中包含配置和'Req'节点,其中包含Request。在'Req'节点内有一个'classId'节点。我在这里存储了一个复杂问题的值。我的最终结果中有一个'appendString'节点。首先,我需要检查“Req”节点内的子节点是否有值。如果它有值,我需要获取节点名称并匹配AllClass / class1 / node3中的节点并获取其值,最后我需要在'appendString'节点内形成一个String,如此'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(&apos;ns:&apos;,$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>  

2 个答案:

答案 0 :(得分:0)

---为回应澄清而编辑---

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:Reqns:classId之外的ns:className下的任何节点都是&#34;子节点&#34;如果不是空的话,需要列出。

答案 1 :(得分:0)

迈克尔先前建议的相反方向,下面是工作的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>