2014-09-23 38 views
1

<Type><values>中的某些<attribute>元素在<comparison><ComparsionList>中具有關聯的<condition>元素。我能夠比較對象和標題並獲得輸出,但是當存在依賴於另一個值的條件時,無法輸出所需的輸出。我想要重構,解析xml值並將它們在xsl中進行比較

這裏是我的XML輸入:

<Types xmlns:p="foo"> 
<Type> 
    <title> TestingOne</title> 
    <values> 
     <attribute name="vala">10</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="valb">20</attribute> 
     <attribute name="valc">15</attribute> 
     <attribute name="vald">45</attribute> 
    </values> 
    <title> TestingThree</title> 
    <values> 
     <attribute name="vala">78</attribute> 
     <attribute name="valb">20</attribute> 
     <attribute name="valc">60</attribute> 
     <attribute name="vald">42</attribute> 
    </values> 
    <title> TestingFour</title> 
    <values> 
     <attribute name="vala">1</attribute> 
     <attribute name="valb">3</attribute> 
     <attribute name="valc">5</attribute> 
     <attribute name="vald">7</attribute> 
    </values> 
<title> TestingFive</title> 
    <values> 
     <attribute name="vala">2</attribute> 
     <attribute name="valb">4</attribute> 
     <attribute name="valc">6</attribute> 
     <attribute name="vald">8</attribute> 
    </values> 

<title> TestingSix</title> 
    <values> 
     <attribute name="vala">2</attribute> 
     <attribute name="valb">4</attribute> 
     <attribute name="valc">6</attribute> 
     <attribute name="vald">8</attribute> 
    </values> 
    </Type> 
    <comparison> 
    <comparisionList> 
     <object>TestingOne</object> 
     <condition>valc=30</condition> 
     <newName>vald</newName> 
     <newValue>60</newValue> 
    </comparisionList> 

    <comparisionList> 
     <object>TestingTwo</object> 
     <condition>valb=40 or valb=20</condition> 
     <newName>vald</newName> 
     <newValue>60</newValue> 
    </comparisionList> 

    <comparisionList> 
     <object>TestingThree</object> 
     <newName>vale</newName> 
     <newValue>100</newValue> 
    </comparisionList> 
     <comparisionList> 
     <object>TestingFour</object> 
     <condition>valc!=3</condition> 
     <newName>vald</newName> 
     <newValue>9</newValue> 
    </comparisionList> 

    </comparisionList> 
     <comparisionList> 
     <object>TestingSix</object> 
     <condition>vala!=vala</condition> 
     <newName>vald</newName> 
     <newValue>20</newValue> 
    </comparisionList> 

     <comparisionList> 
     <object>TestingSix</object> 
     <condition>!valb</condition> 
     <newName>vald</newName> 
     <newValue>1000</newValue> 
    </comparisionList> 
</comparison> 
</comparison> 

</Types> 

這裏我的xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:p="foo" xmlns:ns1="bar"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:template match="/Types"> 
    <objects> 
     <xsl:for-each select="/Type"> 
        <xsl:element name="{title}"> 
        <xsl:for-each select="values/attribute"> 
         <xsl:element name="{@name}"> 
          <xsl:value-of select="text()"/> 
         </xsl:element> 
        </xsl:for-each> 
        <xsl:variable name="attributes" select="values/*"/> 
        <xsl:variable name="newPath" select="/Types/Type/[object=$attributes]"/> 
        <template> 
         <xsl:value-of select="$newPath/newName"/> 
         <xsl:value-of select="$newPath/newValue"/> 
        </template> 
       </xsl:element> 
      </xsl:for-each> 
    </objects> 
</xsl:template> 
</xsl:stylesheet> 

這裏是預期輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<template> 
<testingone> 
<vala>10</vala> 
<valb>20</valb> 
<valc>30</valc> 
<vald>60</vald> 
</testingone> 

<testingTwo> 
<vala>10</vala> 
<valb>20</valb> 
<valc>15</valc> 
<vald>60</vald> 
</testingTwo> 

<testingThree> 
<vala>78</vala> 
<valb>20</valb> 
<valc>60</valc> 
<vald>100</vald> 
</testingThree> 
</template> 
+0

輸入數據和xsl不是有效的xml。您的選擇器p:objectSet/p:objects/p:object在輸入文檔中不存在。 – terrywb 2014-09-23 18:33:36

+0

你真的在問如何評估'valb = 40或valb = 20'這樣的字符串,如'condition'元素所示? – 2014-09-23 19:21:22

+0

這是正確的TIM,並將它們與 user4071541 2014-09-23 19:39:37

回答

1

只給一個可能的解決方案,以獲得所需的輸出 - 我不會提供完整的解決方案,但它的一部分。在您的比較列表中有兩種不同的方法(具有應該評估的條件或僅替換或不添加條件的條件,對於3d組),您預期的輸出與我期望的第三組不同:

<comparisionList> 
    <object>TestingThree</object> 
    <newName>vale</newName> 
    <newValue>100</newValue> 
</comparisionList> 

因此,無論您想將<vale>100</vale>附加到TestingThree組中,還是您提及的預計存在<vald>100</vald>的錯字。
對於這兩個選項,我想讓你知道如何調整以下情況,以便它幾乎可以滿足你的需求,並且應該可以輕鬆添加。
儘管我知道這不是最好的解決方案,但它至少提供了一種可能的方法,並且已經爲testingOne和TestingTwo提供了請求的輸出。

下面的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="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: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="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="toBeChecked" select="'default'"/> 
<xsl:variable name="testGroupName" select="$groupName"/> 
<xsl:variable name="attributeName" select="."/> 
<xsl:variable name="testCondition" 
    select="normalize-space(//comparisionList/object[normalize-space(.) 
    =$testGroupName]/parent::*/condition)"/> 
<xsl:variable name="conditionNewName" 
    select="normalize-space(//comparisionList/object[normalize-space(.) 
    =$testGroupName]/parent::*/newName)"/> 
<xsl:variable name="conditionNewValue" 
    select="normalize-space(//comparisionList/object[normalize-space(.) 
=$testGroupName]/parent::*/newValue)"/> 
<xsl:variable name="conditionRules" select="tokenize($testCondition,'or')"/> 
<xsl:for-each select="tokenize($testCondition,'or')"> 
    <xsl:variable name="conditionParams" 
     select="tokenize(normalize-space(.),'=')"/> 
    <xsl:variable name="conditionName" select="$conditionParams[1]"/> 
    <xsl:variable name="conditionValue" select="$conditionParams[2]"/> 
    <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> 

輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<OutPut> 
<TestingOne> 
    <vala>10</vala> 
    <valb>20</valb> 
    <valc>30</valc> 
    <vald>60</vald> 
</TestingOne> 
<TestingTwo> 
    <vala>10</vala> 
    <valb>20</valb> 
    <valc>15</valc> 
    <vald>60</vald> 
</TestingTwo> 
<TestingThree> 
    <vala>78</vala> 
    <valb>20</valb> 
    <valc>60</valc> 
    <vald>42</vald> 
</TestingThree> 
</OutPut> 

雖然它可能是很明顯這種方法是如何工作的,只是一個簡短的解釋:首先檢查是否有在比較列表中給出的條件替換測試組中的值。如果沒有,只需從組中創建元素而不做任何更改。如果給出了一個條件,則在所有屬性上以不同模式應用模板,並將參數設置爲應該更改的元素的名稱以及此元素的新值。

+0

謝謝你的更新,但我得到以下錯誤試圖運行它11:40:06,709錯誤[main] JAXPSAXProcessorInvoker - 錯誤檢查表達式的類型'funcall(tokenize,[variable-ref(testCondition/string),literal-expr要麼)])'。 javax.xml.transform.TransformerConfigurationException:檢查表達式'funcall(tokenize,[variable-ref(testCondition/string),literal-expr(or)])'的類型時出錯。 – user4071541 2014-09-24 15:42:43

+0

我解決了,非常感謝你 – user4071541 2014-09-24 15:47:57

相關問題