簡體   English   中英

使用XSLT創建僅具有不同路徑的XML

[英]Create XML with only distinct paths using XSLT

我想創建一個僅包含節點名稱的XML,該節點名稱在源文檔中具有不同的路徑。 該值並不重要,它可以為空或偽值。 換句話說,生成的文檔應僅包含源文檔的(節點)本質。

我找到了一個答案(鏈接: 如何使用XSLT列出完整的XML文檔 ),它指向一個非常相似的問題,該問題指向正確的方向,但這並不是我所要尋找的。

使用提到的帖子的修改示例:

原始文件:

<?xml version="1.0" encoding="UTF-8"?>
<MediaCatalog name="AccessoriesCatalog">
    <Category Definition="AccessoriesCategory"
    name="1532" id="1532">
    </Category>
    <Category Definition="AccessoriesCategory"
    name="16115" id="16115">
        <ParentCategory>1532</ParentCategory>
    </Category>
    <Category Definition="AccessoriesCategory"
    name="16116" id="16116">
        <ParentCategory>16115</ParentCategory>
    </Category>
    <Category Definition="AccessoriesCategory"
    name="16126" id="16126">
        <ParentCategory>16115</ParentCategory>
            <genre>
                <id>17</id>
                <name>Fairy Tales</name>
           </genre>
    </Category>
    <Category Definition="AccessoriesCategory"
    name="16131" id="16131">
        <ParentCategory>1532</ParentCategory>
    </Category>
    <Category Definition="AccessoriesCategory"
    name="16132" id="16132">
        <ParentCategory>16131</ParentCategory>
            <language>
                <id>1</id>
                <name>English</name>
                <shortName>EN</shortName>
            </language>
    </Category>
    <Category Definition="AccessoriesCategory"
    name="16136" id="16136">
        <ParentCategory>16131</ParentCategory>
            <genre>
                <id>18</id>
                <name>Thriller</name>
           </genre>
    </Category>
    <Category Definition="AccessoriesCategory"
    name="16139" id="16139">
        <ParentCategory>16131</ParentCategory>
    </Category>
    <Category Definition="AccessoriesCategory"
    name="16144" id="16144">
        <ParentCategory>16131</ParentCategory>
        <subCategory>
            <label>
                <id>444</id>
                <name>label444</name>
            </label>
        </subCategory>
    </Category>
    <Category Definition="AccessoriesCategory"
    name="16195" id="16195">
        <ParentCategory>16131</ParentCategory>
    </Category>
</MediaCatalog>

生成的文檔應如下所示:

<MediaCatalog>
    <Category>
        <ParentCategory>
        </ParentCategory>
        <genre>
            <id></id>
            <name></name>
        </genre>
        <language>
            <id></id>
            <name></name>
            <shortName></shortName>
        </language>
        <subCategory>
            <label>
                <id></id>
                <name></name>
            </label>
        </subCategory>
    </Category>
</MediaCatalog>

根據我針對類似問題找到的答案,我提出了以下轉換以實現這一目標:

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

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

 <xsl:template match="
  *[generate-id()
   =
    generate-id(key('kElemByName', local-name())[1])
   ]">
  <xsl:value-of select="concat('&lt;', local-name(), '&gt;', '&#xA;')" disable-output-escaping="yes" />
  <xsl:apply-templates select="*"/>
  <xsl:value-of select="concat('&lt;/', local-name(), '&gt;', '&#xA;')" disable-output-escaping="yes" />
 </xsl:template>
 <xsl:template match="text()">
 </xsl:template>
</xsl:stylesheet>

但是,這沒有給我正確的答案,因為Muenchian分組方法的關鍵字僅基於使用函數local-name()的節點名稱。

因此,將其應用到我得到的上面的源xml中,而不是正確的輸出是:

<?xml version="1.0" encoding="UTF-8"?>
<MediaCatalog>
    <Category>
    </Category>
    <ParentCategory>
    </ParentCategory>
    <genre>
        <id>
        </id>
        <name>
        </name>
    </genre>
    <language>
        <shortName>
        </shortName>
    </language>
    <subCategory>
        <label>
        </label>
    </subCategory>
</MediaCatalog>

為了創建正確的輸出,有必要使用完整的節點路徑作為鍵,而不是僅使用節點名稱。 問題是在XSLT中這怎么可能,因為據我所知,沒有諸如getFullPath()之類的內置函數可以獲取當前節點的完整路徑。

以下XSLT產生所需的輸出(除了縮進不好的事實之外):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    version="2.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="*"/>

  <!-- Template for recursive handling of the child nodes. 
       Note that these nodes originate from different parents belonging to the same group! 
       This is important since we have to scan ALL sub trees of the a group and not only the first one!
  -->
  <xsl:template name="descend">
    <xsl:param name="nodes"/>

    <xsl:for-each-group select="$nodes" group-by="local-name()">

      <xsl:value-of select="concat('&lt;', current-grouping-key(), '&gt;', '&#xA;')" disable-output-escaping="yes" />

      <xsl:call-template name="descend">
        <!-- Call recursively. -->
        <xsl:with-param name="nodes" select="current-group()/*"/>
      </xsl:call-template>

      <xsl:value-of select="concat('&lt;/', current-grouping-key(), '&gt;', '&#xA;')" disable-output-escaping="yes" />

    </xsl:for-each-group>
  </xsl:template>

  <!-- Start the recursion with the children of the root node. -->
  <xsl:template match="/">
    <xsl:call-template name="descend">
      <xsl:with-param name="nodes" select="*"/>
    </xsl:call-template>    
  </xsl:template>

</xsl:stylesheet>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM