2013-03-10 64 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