2014-10-29 77 views
1

我需要一些帮助,解决我的xslt代码中的问题。 用于处理器/调试& IDE:(满含泪水下来只是为了我需要为我选择的要素)在MS Visual Studio中MSXML 6.0 2012年XSLT 1.0获取不同的值失败

我准确输入

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <components> 
    <Object3D id="130" plName="STF45668"/> 
    <Object3D id="131" plName="RIOD122"/> 
    <Object3D id="132" plName="RIOD122"/> 
    <Object3D id="133" plName="RIOD122"/> 
    <Object3D id="182" plName="RIOD124"/> 
    <Object3D id="183" plName="RIOD124"/> 
    <Object3D id="184" plName="RIOD124"/> 
    <Object3D id="185" plName="RIOD124"/> 
    </components> 
</root> 

我的XSLT:

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:msxsl="urn:schemas-microsoft-com:xslt"> 
    <xsl:key name ="objectsByName" use="/root/components/Object3D" match="@plName"/> 
    <xsl:output media-type="text"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
    <xsl:variable name="allObjs" select="//Object3D"/> 
    <xsl:variable name="distinctObjsCount" 
        select="//Object3D[count(. | key('objectsByName', @plName)[1]) = 1]"/> 
    <xsl:variable name="distinctObjsGenID" 
        select="//Object3D[generate-id() = 
          generate-id(key('objectsByName', @plName)[1])]"/> 

    <xsl:for-each select="//Object3D[count(. | key('objectsByName', @plName)[1]) = 1]"> 
     <xsl:value-of select="concat(@plName, '(',count(key('objectsByName', @plName)),')')"/> 
     <xsl:if test="position() != last()">, </xsl:if> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

这是转换输出我得到:

<?xml version="1.0" encoding="utf-8"?> 
STF45668(0), RIOD122(0), RIOD122(0), RIOD122(0), RIOD124(0), RIOD124(0), RIOD124(0), RIOD124(0) 

但是我无法从这些Object3D元素中获取不同的值。

所以......我不知道为什么这会出错。 有没有人知道我做错了什么?

编辑:现在1:1我正在使用的文件。

+0

请显示完整的XSLT样式表,以便我们可以重现您的问题。另外,完整的XML输入将会有所帮助。谢谢! – 2014-10-29 09:08:45

+0

我不认为你真的想要那样。真正的输入文件有大约5k行程序生成的XML代码,xsl文件也有大约4k行。这是因为我从预制模板创建.odt文件 - >巨大的开销。我能做的是添加与受影响的元素相关的所有属性。 – 2014-10-29 09:30:31

+0

我没有要求10k转储你拥有的所有东西。但是如果你希望人们追踪一个错误/不一致/令人惊讶的结果,你真的必须发布一切,或者b)在你的输入和代码的一小部分中隔离这个问题。否则,所有投注都关闭。 – 2014-10-29 10:02:38

回答

3

您的输入对我而言并不合适。正确的输入XML会是这样的:

<root> 
<components> 
    <Object3D plName="chair" /> 
    <Object3D plName="cup" /> 
    <Object3D plName="desk" /> 
    <Object3D plName="cup" /> 
    <Object3D plName="chair" /> 
    <Object3D plName="chair" /> 
    <Object3D plName="desk" /> 
    <Object3D plName="cup" /> 
</components> 
</root> 

而且,下面的XSLT应该可以正常使用此XML:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/> 
<xsl:key name="Object" match="Object3D" use="@plName"/> 

<xsl:template match="/root/components"> 
    <xsl:for-each select="Object3D[count(. | key('Object', @plName)[1]) = 1]"> 
     <xsl:value-of select="concat(@plName, '(',count(key('Object', @plName)),')')"/> 
     <xsl:if test="position() != last()">, </xsl:if> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

的键用于组Object3D,以及内部的for-each,形成你想要的输出:

chair(3), cup(3), desk(2) 
+0

这是我的问题有趣的部分。 该选择导致返回输入文件的所有Object3D元素。 分组不起作用,因为它应该。 以上代码的输出如下: 椅子(0),椅子(0),椅子(0),杯子(0),杯子(0),杯子(0),桌子(0),桌子0) 相信我,我也对结果感到惊讶。 – 2014-10-29 09:17:03

+0

+1对于XSLT代码 – 2014-10-29 09:21:18

+1

@ steven.eisenreich不,那不是真的 - 至少在撒克逊人的情况下,它的工作原理与上述完全相同。你在使用什么处理器? – 2014-10-29 09:23:28