1

是否有可能得到这样的转变:

源 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>

如果是 - 有人可以给出提示吗?;-)

谢谢你!

4

2 回答 2

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>
于 2013-03-10T14:20:43.350 回答
0

一、本次改造:

<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>

三、此类通用问题的最通用解决方案

看到这个答案:https ://stackoverflow.com/a/8597577/36305

于 2013-03-10T18:33:49.980 回答