Xslt选择条件不适合我。不会以其他方式阻止

时间:2018-01-21 08:32:21

标签: xml xslt

尊敬的先生,

我的样本输入是:

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <Information>
            <jsonObject>
                <_JsonReader_PS_id>1</_JsonReader_PS_id>
                <Guid>1958ac1d-7176-46c1-b767-b871d7ddb0a8</Guid>
                <?xml-multiple  Children?>
                <Children>
                    <_JsonReader_PS_id>2</_JsonReader_PS_id>                    
                    <Items>                     
                        <DefinitionId>
                            <Type>System.Int32</Type>
                            <Value>108</Value>
                        </DefinitionId>                     
                    </Items>
                </Children>
                <Children>
                    <_JsonReader_PS_id>4</_JsonReader_PS_id>                    
                    <?xml-multiple  Children?>
                    <Children>
                    <_JsonReader_PS_id>5</_JsonReader_PS_id>                        
                        <Items>                         
                            <DefinitionId>
                                <Type>System.Int32</Type>
                                <Value>108</Value>
                            </DefinitionId>                         
                        </Items>
                    </Children>                 
                    <Items>                     
                        <DefinitionId>
                            <Type>System.Int32</Type>
                            <Value>108</Value>
                        </DefinitionId>                     
                    </Items>
                </Children>
                <Children>
                    <_JsonReader_PS_id>29</_JsonReader_PS_id>                   
                    <?xml-multiple  Children?>
                    <Items>
                        <DefinitionId>
                            <Type>System.Int32</Type>
                            <Value>108</Value>
                        </DefinitionId>
                    </Items>
                </Children>
                <Items>                 
                    <DefinitionId>
                        <Type>System.Int32</Type>
                        <Value>108</Value>
                    </DefinitionId>                 
                    <Id>
                        <Type>System.Int32</Type>
                        <Value>92</Value>
                    </Id>                   
                </Items>
            </jsonObject>
            <jsonObject>
                <_JsonReader_PS_id>79.0</_JsonReader_PS_id>
                <?xml-multiple  Children?>              
                <Items>
                    <DefinitionId>
                        <Type>System.Int32</Type>
                        <Value>108</Value>
                    </DefinitionId>                 
                </Items>
                <Instance>
                    <_JsonReader_PS_id>179.0</_JsonReader_PS_id>
                    <Items>                     
                        <DefinitionId>
                            <Type>System.Int32</Type>
                            <Value>108</Value>
                            <Original>108</Original>
                        </DefinitionId>                     
                        <Id>
                            <Type>System.Int32</Type>
                            <Value>96</Value>
                        </Id>                       
                    </Items>
                </Instance>
            </jsonObject>
        </Information>
    </soapenv:Body>
</soapenv:Envelope>

有两个&#34; jsonObject&#34;内部信息标签。我正在为每个人运行&#34; jsonObject&#34;并尝试检查&#34; Items / Id / Value&#34;在jsonObject标签内。 如果&#34; Items / Id / Value&#34;不等于92或是否&#34;项目/标识/价值&#34;在jsonObject中不存在。然后我想选择jsonObject,并将其添加到id为92的jsonObject的Children数组中。 这是我尝试过的。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:variable name="firstId" select="92" />
        <xsl:template match="/">
            <jsonObject>
                <xsl:apply-templates/>
            </jsonObject>
        </xsl:template>
        <xsl:template match="Information">
            <xsl:for-each select="jsonObject">            
               <firstId><xsl:value-of select="$firstId"/></firstId>
               <id><xsl:value-of select="Items/Id/Value"/></id>
                <xsl:choose>
                     <xsl:when test="//Items/Id/Value = $firstId">
                       <test1>test1</test1>
                       <xsl:copy-of select="*"/>
                     </xsl:when>
                     <xsl:otherwise>
                        <Children>
                            <test2>test2</test2>
                            <xsl:copy-of select="*"/>
                        </Children>
                     </xsl:otherwise>
                 </xsl:choose>
            </xsl:for-each>
        </xsl:template>
    </xsl:stylesheet>

xslt不会进入内部&#34;否则&#34;阻止,选择,即使&#34; id&#34;在jsonObject中不存在。 这是预期的输出

<?xml version="1.0" encoding="UTF-8"?>
<jsonObject>

    <firstId>92</firstId>
    <id>92</id>
    <test1>test1</test1>
    <_JsonReader_PS_id xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">1</_JsonReader_PS_id>
    <Guid xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">1958ac1d-7176-46c1-b767-b871d7ddb0a8</Guid>
    <Children xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <_JsonReader_PS_id>2</_JsonReader_PS_id>                    
        <Items>                     
            <DefinitionId>
                <Type>System.Int32</Type>
                <Value>108</Value>
            </DefinitionId>                     
        </Items>
    </Children>
    <Children xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <_JsonReader_PS_id>4</_JsonReader_PS_id>                    
        <?xml-multiple Children?>
        <Children>
            <_JsonReader_PS_id>5</_JsonReader_PS_id>                        
            <Items>                         
                <DefinitionId>
                    <Type>System.Int32</Type>
                    <Value>108</Value>
                </DefinitionId>                         
            </Items>
        </Children>                 
        <Items>                     
            <DefinitionId>
                <Type>System.Int32</Type>
                <Value>108</Value>
            </DefinitionId>                     
        </Items>
    </Children>
    <Children xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <_JsonReader_PS_id>29</_JsonReader_PS_id>                   
        <?xml-multiple Children?>
        <Items>
            <DefinitionId>
                <Type>System.Int32</Type>
                <Value>108</Value>
            </DefinitionId>
        </Items>
    </Children>
    <Children xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <_JsonReader_PS_id xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">79.0</_JsonReader_PS_id>
        <Items xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
            <DefinitionId>
                <Type>System.Int32</Type>
                <Value>108</Value>
            </DefinitionId>                 
        </Items>
        <Instance xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
            <_JsonReader_PS_id>179.0</_JsonReader_PS_id>
            <Items>                     
                <DefinitionId>
                    <Type>System.Int32</Type>
                    <Value>108</Value>
                    <Original>108</Original>
                </DefinitionId>                     
                <Id>
                    <Type>System.Int32</Type>
                    <Value>96</Value>
                </Id>                       
            </Items>
        </Instance>
    </Children>
    <Items xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">                   
        <DefinitionId>
            <Type>System.Int32</Type>
            <Value>108</Value>
        </DefinitionId>                 
        <Id>
            <Type>System.Int32</Type>
            <Value>92</Value>
        </Id>                   
    </Items>
    <firstId>92</firstId>
    <id/>
    <test1>test1</test1>        

</jsonObject>

在输出中,应该添加一个子元素,即jsonObject,其中&#34; Items / Id / Value&#34;不存在或不等于92。  我不明白为什么其他条件不起作用,即使jsonObject没有id。  请指导。

我的当前输出如下:

你可以清楚地观察到,在foreach的第二次迭代中,xslt识别&#34; Items / Id / Value&#34;不在场。 观察标签92和。但是它仍然没有进入这个条件测试=&#34; //项目/ Id /值= $ firstId&#34;

<?xml version="1.0" encoding="UTF-8"?>
<jsonObject>

    <firstId>92</firstId>
    <id>92</id>
    <test1>test1</test1>
    <_JsonReader_PS_id xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">1</_JsonReader_PS_id>
    <Guid xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">1958ac1d-7176-46c1-b767-b871d7ddb0a8</Guid>
    <Children xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <_JsonReader_PS_id>2</_JsonReader_PS_id>                    
        <Items>                     
            <DefinitionId>
                <Type>System.Int32</Type>
                <Value>108</Value>
            </DefinitionId>                     
        </Items>
    </Children>
    <Children xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <_JsonReader_PS_id>4</_JsonReader_PS_id>                    
        <?xml-multiple Children?>
        <Children>
            <_JsonReader_PS_id>5</_JsonReader_PS_id>                        
            <Items>                         
                <DefinitionId>
                    <Type>System.Int32</Type>
                    <Value>108</Value>
                </DefinitionId>                         
            </Items>
        </Children>                 
        <Items>                     
            <DefinitionId>
                <Type>System.Int32</Type>
                <Value>108</Value>
            </DefinitionId>                     
        </Items>
    </Children>
    <Children xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <_JsonReader_PS_id>29</_JsonReader_PS_id>                   
        <?xml-multiple Children?>
        <Items>
            <DefinitionId>
                <Type>System.Int32</Type>
                <Value>108</Value>
            </DefinitionId>
        </Items>
    </Children>
    <Items xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">                   
        <DefinitionId>
            <Type>System.Int32</Type>
            <Value>108</Value>
        </DefinitionId>                 
        <Id>
            <Type>System.Int32</Type>
            <Value>92</Value>
        </Id>                   
    </Items>
    <firstId>92</firstId>
    <id/>
    <test1>test1</test1>
    <_JsonReader_PS_id xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">79.0</_JsonReader_PS_id>
    <Items xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <DefinitionId>
            <Type>System.Int32</Type>
            <Value>108</Value>
        </DefinitionId>                 
    </Items>
    <Instance xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <_JsonReader_PS_id>179.0</_JsonReader_PS_id>
        <Items>                     
            <DefinitionId>
                <Type>System.Int32</Type>
                <Value>108</Value>
                <Original>108</Original>
            </DefinitionId>                     
            <Id>
                <Type>System.Int32</Type>
                <Value>96</Value>
            </Id>                       
        </Items>
    </Instance>

</jsonObject>

在此行之后无论我提到的是关于我在下面建议的更改后面临的问题。继续在这里,因为我无法在评论中添加附件和屏幕截图:

enter image description here

要求是在其他情况下新生成的Children元素应该添加到id为92的jsonObject的Children数组中。 请注意输入xml中children元素上方的标记<?xml-multiple Children?>。需要添加到该阵列。 目前的情况是,每当我将其转换为json输出时,最后的Children标记仅优先于现有的Children数组。

实际上,当我将其转换为json时,实际预期输出。应将新的Children添加到id为92的jsonObject的现有子代表中。

我认为最后一个子块必须准确地添加到它在预期输出中的相同位置,以便它仍然作为新添加的元素到jsonObject的现有Children元素,ID为92.但不确定这是否是实际问题以及如何解决它。  请指导。

enter image description here

2 个答案:

答案 0 :(得分:2)

您的测试条件test="//Items/Id/Value = $firstId"正在测试是否任何 Items Id Value $firstId }。它不会测试当前Items Id是否Value等于$firstId

删除两个斜杠将对每个项目进行测试,而不是整个XML,这将与您在id标记中输出的内容相匹配。

test="Items/Id/Value = $firstId"

答案 1 :(得分:1)

查看XSLT脚本中的以下行:

<xsl:when test="//Items/Id/Value = $firstId">

请注意,test条件以//开头,即您检查 是否整个源XML 中至少有一个Items/Id/Value元素 等于$firstId。在您的情况下,这始终是 true

我认为,您应该删除//个字符,即检查每个Items/Id/Value当前 jsonObject

在第一个jsonObject中,一个这样的,在第二个 - ,所以你应该检查这个(内部)对象, 不在整个文档中查找Items/Id/Value个元素。

修改

你所呈现的JSON截图显然是一些进一步的结果 处理XSLT输出。

查看第一个源 jsonObject (id = 92)。 它包含三个 儿童标签和第二个 它们包含一个(内部) Children 标记。

现在将其与屏幕截图的第一部分进行比较 (最多 id = 96 )。 它包含只有一个 Children 标记,所以很可能 你的软件以某种方式“加入”来自XSLT的 Children 标签 结果(对于第一个 jsonObject )。

我假设您提供的内容不是XSLT脚本的任何直接结果 还支持这样的事实,即屏幕截图包含 Lookups PrimaryKey 标记,源XML中不存在。

所以你应该检查一下你的软件对XSLT的作用 输出,而不是在XSLT脚本中查找错误。

注意 否则分支时的奇怪区别。

分支包含“直接”<xsl:copy-of select="*"/>时,而 否则分支<xsl:copy-of select="*"/>中的“信封”<Children> 标签

我认为,您不应该创建此“额外”<Children>标记 在否则分支中,正如您在第二条评论中所写的那样。