如何比较两个xml属性

时间:2014-09-25 01:41:31

标签: xml xslt xpath

目前它比较<title>并进行操作,我也想比较<code>&<title> 感谢

  <Types xmlns:p="foo">
   <Type>
    <title> TestingOne</title>
    <values>
        <attribute name="vala">10</attribute>
        <attribute name="codeCom">code1</attribute>
        <attribute name="valb">20</attribute>
        <attribute name="valc">30</attribute>
        <attribute name="vald">40</attribute>
    </values>
    <title> TestingTwo</title>
    <values>
        <attribute name="vala">10</attribute>
       <attribute name="codeCom">code2</attribute>
        <attribute name="valb">20</attribute>
        <attribute name="valc">15</attribute>
        <attribute name="vald">45</attribute>
    </values>
   </Type>
   <comparison>
    <comparisionList>
        <object>TestingOne</object>
        <condition>valc=30</condition>
        <code>Code1</code>
        <newName>vald</newName>
        <newValue>60</newValue>
    </comparisionList>
    <comparisionList>
        <object>TestingTwo</object>
        <condition>valb=40 or valb=20</condition>
        <code>Code2</code>
        <newName>vald</newName>
        <newValue>60</newValue>
    </comparisionList>
   </comparison>
  </Types>

XSL就在这里

                <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings">
            <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

            <xsl:template match="/*">
              <xsl:apply-templates select="Type"/>
            </xsl:template>

            <xsl:template match="Type">
             <OutPut>
               <xsl:apply-templates select="values"/>
             </OutPut>
            </xsl:template>

            <xsl:template match="values">
             <xsl:variable name="testName"  
              select="normalize-space(./preceding-sibling::title[1])"/>
             <xsl:variable name="testCode"  
              select="normalize-space(attribute[@name='code'])"/>
             <xsl:element name="{$testName}">
             <xsl:variable name="checkIfCondition">
              <xsl:apply-templates  select="./attribute" mode="attributeCheck">
               <xsl:with-param name="groupName" select="$testName"/>
               <xsl:with-param name="codeName" select="$testCode"/>
               <xsl:with-param name="toBeChecked" select="'shouldReplace'"/>
              </xsl:apply-templates>
             </xsl:variable>

             <xsl:variable name="checkConditionName">
               <xsl:apply-templates  select="./attribute" mode="attributeCheck">
                <xsl:with-param name="groupName" select="$testName"/>
                <xsl:with-param name="toBeChecked" select="'shouldReplaceName'"/>
               </xsl:apply-templates>
             </xsl:variable>

             <xsl:variable name="checkConditionValue">
               <xsl:apply-templates  select="./attribute" mode="attributeCheck">
                <xsl:with-param name="groupName" select="$testName"/>
                <xsl:with-param name="toBeChecked" select="'shouldReplaceValue'"/>
               </xsl:apply-templates>
             </xsl:variable>

             <xsl:choose>
               <xsl:when test="$checkIfCondition ='true'">
                  <xsl:apply-templates  select="./attribute" mode="attributeChange">
                     <xsl:with-param name="groupName" select="$testName"/>
                     <xsl:with-param name="changeName" select="$checkConditionName"/>
                     <xsl:with-param name="changeValue" select="$checkConditionValue"/>
                  </xsl:apply-templates>
               </xsl:when>
               <xsl:otherwise>
                  <xsl:apply-templates  select="./attribute" mode="attributes"/>
               </xsl:otherwise>
              </xsl:choose>
             </xsl:element>
            </xsl:template>

            <xsl:template match="attribute" mode="attributeCheck">
                <xsl:param name="groupName"/>
                <xsl:param name="codeName"/>
                <xsl:param name="toBeChecked" select="'default'"/>
                <xsl:variable name="attributeName" select="."/>

             <xsl:variable name="testComparisionList" 
                  select="//comparisionList
                            [normalize-space(object) = $groupName and normalize-space(code) = $codeName]"/>

             <xsl:variable name="testCondition" 
                  select="normalize-space($testComparisionList/condition)"/>

            <xsl:variable name="conditionNewName" 
               select="normalize-space(//comparisionList/object[normalize-space(.)
              =$groupName]/parent::*/newName)"/>
            <xsl:variable name="conditionNewValue" 
              select="normalize-space(//comparisionList/object[normalize-space(.)
             =$groupName]/parent::*/newValue)"/>
            <xsl:variable name="conditionRules" select="str:tokenize($testCondition,'or')"/>
            <xsl:for-each select="str:tokenize($testCondition,'or')">
              <xsl:variable name="conditionParams" 
                   select="str:tokenize(normalize-space(.),'=')"/>
              <xsl:variable name="conditionName" select="$conditionParams[1]"/>
              <xsl:variable name="conditionValue" select="$conditionParams[2]"/>

              <xsl:key name="compare" 
     match="comparisionList" 
     use="concat(normalize-space(object), '|', normalize-space(code))" />

     <xsl:variable name="testComparisionList" 
  select="key('compare', concat($groupName, '|', $codeName))"/>




              <xsl:choose>
                <xsl:when test="$attributeName/@name = $conditionName 
                          and $attributeName = $conditionValue">
                  <xsl:choose>
                     <xsl:when test="$toBeChecked='shouldReplace' ">
                       <xsl:text>true</xsl:text>
                     </xsl:when>
                     <xsl:when test="$toBeChecked='shouldReplaceName'">
                       <xsl:value-of select="$conditionNewName"/>
                     </xsl:when>
                     <xsl:when test="$toBeChecked='shouldReplaceValue'">
                       <xsl:value-of select="$conditionNewValue"/>
                     </xsl:when>
                     <xsl:otherwise></xsl:otherwise>
              </xsl:choose>
             </xsl:when>
             <xsl:otherwise></xsl:otherwise>
            </xsl:choose>
            </xsl:for-each>
            </xsl:template>

            <xsl:template match="attribute" mode="attributes">
            <xsl:param name="groupName"/>
            <xsl:variable name="testGroupName" select="$groupName"/>
            <xsl:value-of select="$testGroupName"/>
            <xsl:element name="{./@name}">
              <xsl:value-of select="."/>
            </xsl:element>
            </xsl:template>

            <xsl:template match="attribute" mode="attributeChange">
            <xsl:param name="groupName"/>
            <xsl:param name="changeName"/>
            <xsl:param name="changeValue"/>
            <xsl:choose>
              <xsl:when test="$changeName = ./@name">
                <xsl:element name="{./@name}">
                  <xsl:value-of select="$changeValue"/>
                </xsl:element>
              </xsl:when>
              <xsl:otherwise>
               <xsl:element name="{./@name}">
                <xsl:value-of select="."/>
               </xsl:element>
              </xsl:otherwise>
             </xsl:choose>
            </xsl:template>
            </xsl:stylesheet>

目前它比较<title>并在xslt中进行操作,我也想比较<code>&<title>。 我在想select="normalize-space(./preceding-sibling::[title[1] and [code])"/>之类的东西 感谢

1 个答案:

答案 0 :(得分:1)

如果您在“属性”模板中包含了信息,那将会有所帮助,因为关键的是,它目前在哪里比较title元素。

看看你之前的问题,我假设这个当前的问题随之而来,“属性”模板就像这样开始......

<xsl:template match="attribute" mode="attributeCheck">
    <xsl:param name="groupName"/>
    <xsl:param name="toBeChecked" select="'default'"/>

    <xsl:variable name="testGroupName" select="$groupName"/>

    <xsl:variable name="testCondition" 
          select="normalize-space(//comparisionList/object[normalize-space(.)
                    = $testGroupName]/parent::*/condition)"/>

重新编写testCondition变量可能会有所帮助,只能获取变量中的comparisionList元素,然后可以将其重新用于获取后续的子元素。

 <xsl:variable name="testComparisionList" 
      select="//comparisionList[normalize-space(object) = $groupName]"/>

 <xsl:variable name="testCondition" 
      select="normalize-space($testComparisionList/condition)"/>

(注意,我还删除了稍微不必要的testGroupName变量,因为它与groupName变量完全相同)

所以,你需要做的是传递code并将其添加到comparisonList上的xpath条件

<xsl:template match="attribute" mode="attributeCheck">
    <xsl:param name="groupName"/>
    <xsl:param name="codeName"/>
    <xsl:param name="toBeChecked" select="'default'"/>

 <xsl:variable name="testComparisionList" 
      select="//comparisionList
                [normalize-space(object) = $groupName and normalize-space(code) = $codeName]"/>

 <xsl:variable name="testCondition" 
      select="normalize-space($testComparisionList/condition)"/>

要调用模板,您就可以执行此操作

<xsl:template match="values">
 <xsl:variable name="testName"  
  select="normalize-space(./preceding-sibling::title[1])"/>
 <xsl:variable name="testCode"  
  select="normalize-space(attribute[@name='code'])"/>
 <xsl:element name="{$testName}">
 <xsl:variable name="checkIfCondition">
  <xsl:apply-templates  select="./attribute" mode="attributeCheck">
   <xsl:with-param name="groupName" select="$testName"/>
   <xsl:with-param name="codeName" select="$testCode"/>
   <xsl:with-param name="toBeChecked" select="'shouldReplace'"/>
  </xsl:apply-templates>
 </xsl:variable>

编辑:查找comparisionList的更有效方法是定义密钥。要使用title和element查找它们,您可以像这样定义一个键

<xsl:key name="compare" 
         match="comparisionList" 
         use="concat(normalize-space(object), '|', normalize-space(code))" />

然后testComparisionList的设置如下:

 <xsl:variable name="testComparisionList" 
      select="key('compare', concat($groupName, '|', $codeName))"/>