如何将xml字符串属性分配给xslt中的变量

时间:2014-09-23 21:55:17

标签: xml xslt

我试图查看输入objectType,value0是否存在于Types / Type中,并检查条件以使用输出xml中的T​​ypes / Type的兄弟属性名称值。 这是输入xml:

<?xml version="1.0" encoding="UTF-8"?>
<outPut>
  <object>
    <objectType>TestOne</objectType>
    <Attributes>
      <attribute name="value0">codeOne</attribute>
      <attribute name="value1">35</attribute>
      <attribute name="value2">35</attribute>
    </Attributes>
    <objectType>TestTwo</objectType>
    <Attributes>
      <attribute name="value0">codeTwo</attribute>
      <attribute name="value1">25</attribute>
      <attribute name="value2">35</attribute>
    </Attributes>
    <objectType>TestThree</objectType>
    <Attributes>
      <attribute name="value0">codeThree</attribute>
      <attribute name="value1">25</attribute>
      <attribute name="value2">3225</attribute>
      <attribute name="value3">225</attribute>
    </Attributes>
    <objectType>TestFour</objectType>
    <Attributes>
      <attribute name="value0">codeFour</attribute>
      <attribute name="value1">25</attribute>
      <attribute name="value2">35</attribute>
    </Attributes>
    <objectType>TestFive</objectType>
    <Attributes>
      <attribute name="value0">codeFive</attribute>
      <attribute name="value1">2</attribute>
      <attribute name="value2">3225</attribute>
      <attribute name="value3">225</attribute>
    </Attributes>
    <objectType>TestSix</objectType>
    <Attributes>
      <attribute name="value0">codSix</attribute>
      <attribute name="value1">2</attribute>
      <attribute name="value2">3225</attribute>
      <attribute name="value3">225</attribute>
    </Attributes>
  </object>
  <Types>
    <Type>
      <temp>TestOne</temp>
      <ID>2847</ID>
      <Is_Ingest>0</Is_Ingest>
      <Category>NAV</Category>
      <CategoryTwo>NAVAid</CategoryTwo>
      <Class>codeOne</Class>
      <New_Attribute>nisting</New_Attribute>
      <New_Value>52</New_Value>
      <Condition>value1=35</Condition>
    </Type>
    <Type>
      <temp>TestTwo</temp>
      <ID>2847</ID>
      <Is_Ingest>0</Is_Ingest>
      <Category>NAV</Category>
      <CategoryTwo>NAVAid</CategoryTwo>
      <Class>codeTwo</Class>
      <New_Attribute>nisting</New_Attribute>
      <New_Value>53</New_Value>
      <Condition>value1!=33</Condition>
    </Type>
    <Types>
      <Type>
        <temp>TestThree</temp>
        <ID>28247</ID>
        <Is_Ingest>0</Is_Ingest>
        <Category>NAV</Category>
        <CategoryTwo>NAVAid</CategoryTwo>
        <Class>codeThree</Class>
        <New_Attribute>nisting</New_Attribute>
        <New_Value>52</New_Value>
        <Condition>value1=35</Condition>
      </Type>
      <Type>
        <temp>TestFour</temp>
        <ID>2847</ID>
        <Is_Ingest>0</Is_Ingest>
        <Category>NAV</Category>
        <CategoryTwo>NAVAid</CategoryTwo>
        <Class>codeFour</Class>
        <New_Attribute>AidM</New_Attribute>
        <New_Value>45</New_Value>
        <Condition>value1!=33 & value1!=28</Condition>
      </Type>
      <Type>
        <temp>TestFive</temp>
        <ID>2847</ID>
        <Is_Ingest>0</Is_Ingest>
        <Category>NAV</Category>
        <CategoryTwo>Aid</CategoryTwo>
        <Class>codeFive</Class>
        <New_Attribute>AidM</New_Attribute>
        <New_Value>4</New_Value>
        <Condition>!value</Condition>
      </Type>
      <Type>
        <temp>TestSix</temp>
        <ID>2847</ID>
        <Is_Ingest>0</Is_Ingest>
        <Category>NAV</Category>
        <CategoryTwo>Aid</CategoryTwo>
        <Class>codeSix</Class>
        <New_Attribute>AidM</New_Attribute>
        <New_Value>4</New_Value>
      </Type>
    </Types>
  </outPut>

这是xsl

<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="*"/>
    <xsl:template match="/Input">
        <objects>
            <xsl:for-each select="Output">
                <object type="{object/objectType}">
                    <xsl:variable name="attributes" select="Attributes/*"/>
                    <xsl:variable name="matching-template" select="/Output/Types/Type[temp=$attributes and class=$attributes]"/>
                    <template>
                        <xsl:value-of select="$matching-template/New_Attribute"/>
                        <xsl:value-of select="$matching-template/New_Value"/>
                    </template>
                </object>
            </xsl:for-each>
        </objects>
    </xsl:template>
</xsl:stylesheet>

预期产出

<output>
    <object>
        <objectType>TestOne</objectType>
        <Attributes>
            <attribute name="value0">codeOne</attribute>
            <attribute name="value1">25</attribute>
            <attribute name="value2">35</attribute>
            <attribute name="nisting">52</attribute>
        </Attributes>
        <objectType>TestTwo</objectType>
        <Attributes>
            <attribute name="value0">codeTwo</attribute>
            <attribute name="value1">25</attribute>
            <attribute name="value2">35</attribute>
            <attribute name="NAV">NAVAID</attribute>
            <attribute name="value2">35</attribute>
        </Attributes>
    </object>
</output>

1 个答案:

答案 0 :(得分:0)

注意:以防万一有人想知道这个答案与上面(编辑过)的问题有什么关系:以下是2014年9月23日该问题第一版的接受答案。在2014年10月4日,OP几乎完全改变了(而不只是发布了一个跟进问题)并且答案未被OP接受。为方便起见,原始问题是:

  
    

我想解析以下内容

  
<points>
    <point>
      <A>test=11 or test=12</A>
      <B>pointer> test!=7847</pointer>  
    </point>
</points> 
     

我希望得到像

这样的东西
<out>
<att>test</att>
<att2>=</att>
<att3>or</att3>
<att4>12</att4>
</out>  
     

我使用过类似的东西     <xsl:variable name="A" select="substring(/points/point/test,1)
    它没有帮助获得&#34;或&#34; &#34;和&#34; ......

接受的答案是:

您的XML无效,我想它应该是<B><pointer> test!=7847</pointer></B>而不是<B>pointer> test!=7847</pointer> 虽然不清楚您希望获得所需输出的规则,以及元素名称是静态的还是应该是动态生成的,但是遵循XSLT会起作用:

<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:template match="/*">
     <xsl:apply-templates select="//A"/>
  </xsl:template>

  <xsl:template match="A">
  <xsl:variable name="spaceToken" select="tokenize(., ' ')"/>
  <xsl:variable name="firstEqualToken" select="tokenize($spaceToken[1], '=')"/>
  <xsl:variable name="secondEqualToken" select="tokenize($spaceToken[3], '=')"/>
  <xsl:variable name="equalString" select="substring($spaceToken[1],5,1)"/>
   <out>
    <att>
     <xsl:value-of select="$firstEqualToken[1]"/>
    </att>
    <att2>
     <xsl:value-of select="$equalString"/>
    </att2>
    <att3>
     <xsl:value-of select="$spaceToken[2]"/>
    </att3>
    <att4>
     <xsl:value-of select="$secondEqualToken[2]"/>
   </att4>
  </out>
</xsl:template>
</xsl:stylesheet>

输出:

<?xml version="1.0" encoding="UTF-8"?>
<out>
 <att>test</att>
 <att2>=</att2>
 <att3>or</att3>
 <att4>12</att4>
</out>  

为了增加一些可能更有价值的东西 - 你的select语句select="substring(/points/point/test,1)不会像预期的那样工作 - substring()是一个使用字符串的函数,/points/point是一个开始一个不会得到&#34;测试&#34;的xpath在A文本中。 &#34;测试&#34;是名为&#34; A&#34;的节点文本值的一部分。您将获得该文字,例如使用xpath //points/point/A/text()。您可以按照以下substring()应用substring(string, startpoint, length) - 函数,以便获得&#34; =&#34; in&#34; test = 11&#34;对于$test='test=11'它的substring($test, 5, 1)

参考:W3C - XPath - substring,也许有兴趣在第一个答案中提供一个很好的解释:XPath - Difference between node() and text()

更新:对于下面评论中提到的问题,如何处理!=中的<B> test!=7847</B> - 这取决于。因为它不清楚 1),如果OP中给出的XML是唯一可能要处理的输入,或者是否有各种不同的方程要分割并且 2)< / strong>输出应该如何以及为什么看起来像OP中的建议输出 已经提到输出应该&#34;看起来像&#34;建议的输出,但最好是给出整个预期的输出,因为我只是想知道为什么<A>test=11 or test=12</A>缺少11。我希望所需的输出应该代表所有可能的条件,例如名称(测试),条件(=),要检查相等的值(11和/或12)。也许只有最大值才有意义? 进一步的问题是: 3)如果只有基于平等的条件是可能的 - =!= - 或者它是否可能,例如<>处于输入状态, 4),如果可能有超过2个可选测试表达式且 5 )如果这些条件始终是可选的(使用or),或者也可以包括(使用and)。
最后我不得不承认,我不确定你的意思&#34;如何改变&#39; =&#39;等于和&#39;!=&#39;不等于比较值&#34; - 您想要示例输出<att2>equals</att2>而不是<att2>=</att2>吗?

回到评论中的第一个问题 - 如果您应该编写第二个匹配<B>的模板来处理!= - 不知道可能的输入,那就不容易给出任何咨询。我预计<point>可能有两个以上的条目(C,D,..),并且<A>可能包含使用的表达式!=<B>包含使用=的表达式。因此,我建议使用更动态的方法 - 使用匹配<point>所有子项的模板,检查每个子项中的每个文本是否包含逻辑运算符(and / or) ,然后通过首先检查是否包含test=12来处理每个表达式test!=12!=) - 如果是,则标记为!=,如果不是,请检查是否{{1} }包含,if,然后对=进行标记,并生成动态元素,因为给定的=条件只会产生3个元素 - <B>,也会因为问题<att>test</att> <att2>!=</att> <att>7847</att>以上。

如果需要进一步输入,如果您只是更新您的问题以提供更多信息,将会很有帮助;不一定通过回答我提到的所有问题,但至少考虑它们,而不是更容易帮助你获得所需的输出。