2013-03-10 62 views
1

之一,是有可能得到這樣的轉變:溢出與X元素一個節點到X節點與這些元素

源XML:

<Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>Continental GT (2006-)</model> 
    <model>Continental Flying Spur (2006-)</model> 
    <width>9</width> 
    <wheel_size>20</wheel_size> 
    <offset>40</offset> 
    <bolt_pattermn>5x112</bolt_pattermn> 
    <brand>AEZ</brand> 
    <Velg_ID>AEZ Myta</Velg_ID> 
    <kit1>DK-ZJAE x1</kit1> 
</Item> 

目標XML:

<Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>Continental GT (2006-)</model> 
    <width>9</width> 
    <wheel_size>20</wheel_size>  
    <offset>40</offset> 
    <bolt_pattermn>5x112</bolt_pattermn> 
    <brand>AEZ</brand> 
    <Velg_ID>AEZ Myta</Velg_ID> 
    <kit1>DK-ZJAE x1</kit1> 
    <qty_available>8.00000000</qty_available> 
    <price>174.00</price> 
    <picture>41010</picture> 
    <pkpcena>195.4999</pkpcena> 
</Item> 
<Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>Continental Flying Spur (2006-)</model> 
</Item> 

在源XML中,1個節點有X個元素,X節點必須分成1個元素。目標XML可以包含所有元素,如源代碼或僅包含元素<vehicle><model>

如果是 - 有人可以提示嗎? ;-)

謝謝!

回答

1

這將做到這一點:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/"> 
    <root> 
     <xsl:apply-templates select="//model" mode="split" /> 
    </root> 
    </xsl:template> 

    <xsl:template match="model" mode="split"> 
    <xsl:apply-templates select=".."> 
     <xsl:with-param name="currentModel" select="." /> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="Item"> 
    <xsl:param name="currentModel" /> 

    <xsl:copy> 
     <xsl:apply-templates 
     select="@* | node()[not(self::model)] | $currentModel" /> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

當適用於您的樣品輸入,這將產生:

<root> 
    <Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>Continental GT (2006-)</model> 
    <width>9</width> 
    <wheel_size>20</wheel_size> 
    <offset>40</offset> 
    <bolt_pattermn>5x112</bolt_pattermn> 
    <brand>AEZ</brand> 
    <Velg_ID>AEZ Myta</Velg_ID> 
    <kit1>DK-ZJAE x1</kit1> 
    </Item> 
    <Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>Continental Flying Spur (2006-)</model> 
    <width>9</width> 
    <wheel_size>20</wheel_size> 
    <offset>40</offset> 
    <bolt_pattermn>5x112</bolt_pattermn> 
    <brand>AEZ</brand> 
    <Velg_ID>AEZ Myta</Velg_ID> 
    <kit1>DK-ZJAE x1</kit1> 
    </Item> 
</root> 

此處,我已經縮短我的上述辦法的實施,從Dimitre的一些指針技術:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="model"> 
    <xsl:apply-templates select=".." mode="gen"> 
     <xsl:with-param name="currentModel" select="." /> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="@* | node()" mode="gen"> 
    <xsl:param name="currentModel" select="/.." /> 

    <xsl:copy> 
     <xsl:apply-templates 
     select="@* | node()[not(self::model)] | $currentModel" 
     mode="gen" /> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="text()" /> 
</xsl:stylesheet> 
+0

謝謝你,非常感謝!它的作品......它不僅僅是「一個提示」! ;-D – 2013-03-10 16:28:00

+0

很高興提供幫助。我只做了一個小小的修改,使得XSLT更簡潔一些,並避免使用'generate-id()'。並且不要忘記將這個答案標記爲已接受。謝謝! :) – JLRishe 2013-03-10 16:43:41

+0

JLRishe,您的解決方案仍然只與「模型」一起工作......如果用戶指定重複元素的名稱會怎麼樣? – 2013-03-10 20:09:56

0

I.該轉化體和灰:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:template match="text()"/> 

<xsl:template match="model"> 
    <xsl:apply-templates select=".." mode="gen"> 
    <xsl:with-param name="pInclude" select="."/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="node()|@*" mode="gen"> 
    <xsl:param name="pInclude" select="/.."/> 
     <xsl:copy> 
     <xsl:apply-templates mode="gen" select= 
     "node()[not(name()=name($pInclude)) or count(.|$pInclude)=1]|@*" > 
     <xsl:with-param name="pInclude" select="$pInclude"/> 
     </xsl:apply-templates> 
     </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

當此XML文檔上施加(提供的一個具有第三model加入和多於一個Item元素):

<t> 
    <Item> 
     <stockcode>XXX1</stockcode> 
     <vehicle>Bentley</vehicle> 
     <model>Continental GT (2006-)</model> 
     <model>Continental Flying Spur (2006-)</model> 
     <model>Galactic Flying Spur (2006-)</model> 
     <width>9</width> 
     <wheel_size>20</wheel_size> 
     <offset>40</offset> 
     <bolt_pattermn>5x112</bolt_pattermn> 
     <brand>AEZ</brand> 
     <Velg_ID>AEZ Myta</Velg_ID> 
     <kit1>DK-ZJAE x1</kit1> 
    </Item> 
    <Item> 
     <stockcode>XXX1</stockcode> 
     <vehicle>Bentley</vehicle> 
     <model>XXX Continental GT (2006-)</model> 
     <model>YYY Continental Flying Spur (2006-)</model> 
     <model>ZZZ Galactic Flying Spur (2006-)</model> 
     <width>9</width> 
     <wheel_size>20</wheel_size> 
     <offset>40</offset> 
     <bolt_pattermn>5x112</bolt_pattermn> 
     <brand>AEZ</brand> 
     <Velg_ID>AEZ Myta</Velg_ID> 
     <kit1>DK-ZJAE x1</kit1> 
    </Item> 
</t> 

產生想要的,正確的結果:

<Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>Continental GT (2006-)</model> 
    <width>9</width> 
    <wheel_size>20</wheel_size> 
    <offset>40</offset> 
    <bolt_pattermn>5x112</bolt_pattermn> 
    <brand>AEZ</brand> 
    <Velg_ID>AEZ Myta</Velg_ID> 
    <kit1>DK-ZJAE x1</kit1> 
</Item> 
<Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>Continental Flying Spur (2006-)</model> 
    <width>9</width> 
    <wheel_size>20</wheel_size> 
    <offset>40</offset> 
    <bolt_pattermn>5x112</bolt_pattermn> 
    <brand>AEZ</brand> 
    <Velg_ID>AEZ Myta</Velg_ID> 
    <kit1>DK-ZJAE x1</kit1> 
</Item> 
<Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>Galactic Flying Spur (2006-)</model> 
    <width>9</width> 
    <wheel_size>20</wheel_size> 
    <offset>40</offset> 
    <bolt_pattermn>5x112</bolt_pattermn> 
    <brand>AEZ</brand> 
    <Velg_ID>AEZ Myta</Velg_ID> 
    <kit1>DK-ZJAE x1</kit1> 
</Item> 
<Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>XXX Continental GT (2006-)</model> 
    <width>9</width> 
    <wheel_size>20</wheel_size> 
    <offset>40</offset> 
    <bolt_pattermn>5x112</bolt_pattermn> 
    <brand>AEZ</brand> 
    <Velg_ID>AEZ Myta</Velg_ID> 
    <kit1>DK-ZJAE x1</kit1> 
</Item> 
<Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>YYY Continental Flying Spur (2006-)</model> 
    <width>9</width> 
    <wheel_size>20</wheel_size> 
    <offset>40</offset> 
    <bolt_pattermn>5x112</bolt_pattermn> 
    <brand>AEZ</brand> 
    <Velg_ID>AEZ Myta</Velg_ID> 
    <kit1>DK-ZJAE x1</kit1> 
</Item> 
<Item> 
    <stockcode>XXX1</stockcode> 
    <vehicle>Bentley</vehicle> 
    <model>ZZZ Galactic Flying Spur (2006-)</model> 
    <width>9</width> 
    <wheel_size>20</wheel_size> 
    <offset>40</offset> 
    <bolt_pattermn>5x112</bolt_pattermn> 
    <brand>AEZ</brand> 
    <Velg_ID>AEZ Myta</Velg_ID> 
    <kit1>DK-ZJAE x1</kit1> 
</Item> 

二,一個更通用的,並且仍然短的轉化,其中在其上分割元素名稱爲(外部)參數被傳遞:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:param name="pName" select="'model'"/> 

<xsl:template match="*"> 
    <xsl:apply-templates select="parent::*[$pName = name(current())]" mode="gen"> 
    <xsl:with-param name="pInclude" select="."/> 
    </xsl:apply-templates> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match="node()|@*" mode="gen"> 
    <xsl:param name="pInclude" select="/.."/> 

     <xsl:copy> 
     <xsl:apply-templates mode="gen" select= 
     "node()[not(name()=name($pInclude)) or count(.|$pInclude)=1]|@*" > 
     <xsl:with-param name="pInclude" select="$pInclude"/> 
     </xsl:apply-templates> 
     </xsl:copy> 
</xsl:template> 
<xsl:template match="text()"/> 
</xsl:stylesheet> 

III。最通用的解決方案,以這種的一般問題:

看到這個答案:https://stackoverflow.com/a/8597577/36305

+0

這不是一個額外的要求。 OP聲明:「在源XML中,有1個節點需要X個元素,X節點必須分成1個元素。」除此之外,正如你前一段時間告訴我的,重要的是要預測OP可能會需要什麼,而不僅僅是解決簡化的例子。提問者過去的問題的一個視圖揭示了類似的XML與單個「」的幾個「」。 – JLRishe 2013-03-10 18:58:20

+0

@JLRishe,是的,但問題的標題是「將1個節點中的2個元素分成2個元素和2個節點」......我編輯了標題,因此現在它不會產生誤導。感謝澄清這一點。我有點困了這個第一個夏天日期節省時間星期天早上(嗯,...中午!),但即使在這種情況下,仍然可以產生顯着更短和更通用的解決方案:) – 2013-03-10 19:10:19