简体   繁体   English

xslt 1.0-使用xslt 1.0如何使xslt适用于多个文档元素

[英]xslt 1.0- Using xslt 1.0 how can I make the xslt work for multiple document elements

This is my XML- 这是我的XML-

<?xml version="1.0" encoding="UTF-8"?>
        <update-all-attributes>
          <document name="http://blah">
            <price>111 USD</price>
            <color>red</color>
            <size>comfort</size>
            <cost>00012-40</cost>
            <shipping>US::Ground:0.00</shipping>
            <cost>00012-40</cost>
            <price>111 USD</price>
            <color>red</color>
            <size>comfort</size>
            <cost>00012-40</cost>
            <shipping>US::Ground:0.00</shipping>
            <cost>00012-40</cost>
            <price>111 USD</price>
            <color>red</color>
            <size>comfort</size>
            <shipping>US::Ground:0.00</shipping>
            <price>111 USD</price>
            <color>red</color>
            <size>comfort</size>
          </document>


<document name="http://blahblah">
    <price>110 USD</price>
    <color>blue</color>
    <size>super</size>
    <cost>00012-41</cost>
    <shipping>US::Ground:0.01</shipping>
    <cost>00012-41</cost>
    <price>110 USD</price>
    <color>blue</color>
    <size>super</size>
    <shipping>US::Ground:0.01</shipping>
    <cost>00012-41</cost>
    <price>110 USD</price>
    <color>blue</color>
    <size>super</size>
    <shipping>US::Ground:0.01</shipping>
    <price>110 USD</price>
    <color>blue</color>
    <size>super</size>
  </document>
</update-all-attributes>

I want my final XML as 我希望我的最终XML为

<?xml version="1.0" encoding="UTF-8"?>
                <document name="http://blah">
                  <price>111 USD</price>
                  <color>red</color>
                  <size>comfort</size>
                  <cost>00012-40,00012-40,00012-40,00012-40</cost>
                  <shipping>US::Ground:0.00,US::Ground:0.00,US::Ground:0.00</shipping>
                </document>
            <document name="http://blahblah">
                  <price>110 USD</price>
                  <color>blue</color>
                  <size>super</size>
                  <cost>00012-41,00012-41,00012-41,00012-41</cost>
                  <shipping>US::Ground:0.01,US::Ground:0.01,US::Ground:0.01</shipping>
                </document>

This is the XSLT used (thanks to Thomas W)- 这是使用的XSLT(感谢Thomas W)-

<?xml version="1.0" encoding="UTF-8"?>
<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:strip-space elements="*"/>

  <xsl:key name="element-by-name" match="document/*" use="local-name()"/>


  <!-- Copy everything, unless other templates say otherwise -->
  <xsl:template match="*|@*">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>


  <!-- Skip elements if there are elements of the same name earlier in the document. 
       Priority is set to 1 so that this template overrides other templates
       and we don't accidentally still get duplicates. -->
  <xsl:template match="*[count(. | key('element-by-name', local-name())[1]) > 1]" priority="1"/>


  <!-- This template is for elements we want to be multi-value -->
  <xsl:template match="shipping | cost">
    <xsl:copy>
      <!-- We step through all elements of the same name -->
      <xsl:for-each select="key('element-by-name', local-name())">
        <xsl:value-of select="."/>
        <xsl:if test="position() != last()">,</xsl:if>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

This is working fine for just one document element, I have multiple document element so how can this work for all the document elements? 这仅对一个文档元素有效,我有多个文档元素,那么如何对所有文档元素起作用?

You can do this by changing the key so that it uses both the name of the element and the unique id of its document parent for the lookup value. 您可以通过更改键来做到这一点,以使其同时使用元素名称和其document父级的唯一ID作为查找值。

<?xml version="1.0" encoding="UTF-8"?>
<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:strip-space elements="*"/>

  <xsl:key name="element-by-name-and-parent" match="document/*" 
           use="concat(local-name(), generate-id(..))"/>

  <!-- Copy everything, unless other templates say otherwise -->
  <xsl:template match="*|@*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <!-- Skip siblings of the same name within the same parent element; only use first occurrence -->
  <xsl:template match="*[count(. | key('element-by-name-and-parent', 
               concat(local-name(), generate-id(..)))[1]) > 1]"
        priority="1"/>

  <!-- This template is for elements we want to be multi-value -->
  <xsl:template match="shipping | cost">
    <xsl:copy>
      <!-- Step through all elements of the same name that belong to the same parent -->
      <xsl:for-each select="key('element-by-name-and-parent', 
                concat(local-name(), generate-id(..)))">
       <xsl:value-of select="."/>
        <xsl:if test="position() != last()">,</xsl:if>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Output (the root element is the same as in the input XML; the output that you asked for in the question has no root element): 输出(根元素与输入XML中的根元素相同;您在问题中要求的输出没有根元素):

<?xml version="1.0" encoding="UTF-8"?>
<update-all-attributes>
   <document name="http://blah">
      <price>111 USD</price>
      <color>red</color>
      <size>comfort</size>
      <cost>00012-40,00012-40,00012-40,00012-40</cost>
      <shipping>US::Ground:0.00,US::Ground:0.00,US::Ground:0.00</shipping>
   </document>
   <document name="http://blahblah">
      <price>110 USD</price>
      <color>blue</color>
      <size>super</size>
      <cost>00012-41,00012-41,00012-41</cost>
      <shipping>US::Ground:0.01,US::Ground:0.01,US::Ground:0.01</shipping>
   </document>
</update-all-attributes>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM