簡體   English   中英

XSLT從以下類型的XML結構中除去除某些節點以外的所有節點

[英]XSLT to remove all but certain nodes from the following type of XML structure

<Rootnode>
    <Properties Attribute ="xxx">
        <Type>1</Type>
        <Size>10</Size>
    </Properties>
    <Other>
        <blah>h</blah>
    </Other>
    <Other2>
        <blah>h</blah>
    </Other2>
    <Properties Attribute ="xxx">
        <xType>5</xType>
        <xSize>10</xSize>
    </Properties>
    <Items>
       <Item4>8</Item4>
    </Items>
    <Items>
       <Item6>8</Item6>
    </Items>
    <Properties Attribute ="xxx">
        <zType>1</zType>
        <zSize>10</zSize>
    </Properties>
    <Items place="UK">
       <Item1>8</Item1>
    </Items>
 </Rootnode>

現在,我只想包含屬性和項目。 優選地,如果屬性是相同的名稱和值,則將屬性和項目組連接在一起,並基於屬性對屬性和項目進行排序,並按字母順序對兩個子節點進行排序。 到目前為止,我還是一片空白;(

所需的輸出幾乎與ABach所示的一樣。 盡管我忘了提到的一件事是,每個“屬性”或“項目”上可能還有其他屬性,並且我知道我希望排序的屬性的名稱。 我可以很容易地修改。

即所需的輸出

<?xml version="1.0"?>
<Rootnode>
  <Properties Attribute="xxx">
    <Size>10</Size>
    <Type>1</Type>
    <xSize>10</xSize>
    <xType>5</xType>
    <zSize>10</zSize>
    <zType>1</zType>
  </Properties>
  <Items>
    <Item4>8</Item4>
    <Item6>8</Item6>
  </Items>
  <Items place="UK">
    <Item1>8</Item1>
  </Items>
</Rootnode>

很抱歉,到目前為止我沒有付出很多努力。。。我陷入了混亂,認為並沒有多大幫助。。。

正如@LarsH所指出的那樣,通過不向我們顯示期望的輸出XML,我們可以猜測您真正想要的是什么。 就是說,這是我對XSLT 1.0解決方案的嘗試。

當此XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:key
    name="PropertiesByAttributeNameVal"
    match="Properties"
    use="concat(name(@*[1]), '+', @*[1])" />

  <xsl:key
    name="ItemsByAttributeNameVal" 
    match="Items"
    use="concat(name(@*[1]), '+', @*[1])" />

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

  <xsl:template match="Rootnode">
    <Rootnode>
      <xsl:apply-templates 
        select="Properties[
          generate-id() = 
          generate-id(key(
            'PropertiesByAttributeNameVal',
             concat(name(@*[1]), '+', @*[1]))[1])]">
        <xsl:with-param name="pKeyName"
          select="'PropertiesByAttributeNameVal'" />
        <xsl:sort select="concat(name(@*[1]), '+', @*[1])" />
      </xsl:apply-templates>
      <xsl:apply-templates
        select="Items[
          generate-id() = 
          generate-id(key(
            'ItemsByAttributeNameVal',
            concat(name(@*[1]), '+', @*[1]))[1])]">
        <xsl:with-param name="pKeyName"
          select="'ItemsByAttributeNameVal'" />
        <xsl:sort select="concat(name(@*[1]), '+', @*[1])" />
      </xsl:apply-templates>
    </Rootnode>
  </xsl:template>

  <xsl:template match="Properties|Items">
    <xsl:param name="pKeyName" />
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates
        select="key($pKeyName, concat(name(@*[1]), '+', @*[1]))/*">
        <xsl:sort select="name()" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

...針對提供的XML運行:

<Rootnode>
  <Properties Attribute="xxx">
    <Type>1</Type>
    <Size>10</Size>
  </Properties>
  <Other>
    <blah>h</blah>
  </Other>
  <Other2>
    <blah>h</blah>
  </Other2>
  <Properties Attribute="xxx">
    <xType>5</xType>
    <xSize>10</xSize>
  </Properties>
  <Items>
    <Item4>8</Item4>
  </Items>
  <Items>
    <Item6>8</Item6>
  </Items>
  <Properties Attribute="xxx">
    <zType>1</zType>
    <zSize>10</zSize>
  </Properties>
  <Items place="UK">
    <Item1>8</Item1>
  </Items>
</Rootnode>

...我猜是生成了正確的輸出XML:

<?xml version="1.0"?>
<Rootnode>
  <Properties Attribute="xxx">
    <Size>10</Size>
    <Type>1</Type>
    <xSize>10</xSize>
    <xType>5</xType>
    <zSize>10</zSize>
    <zType>1</zType>
  </Properties>
  <Items>
    <Item4>8</Item4>
    <Item6>8</Item6>
  </Items>
  <Items place="UK">
    <Item1>8</Item1>
  </Items>
</Rootnode>

請注意,如果對稍有修改的XML文檔(具有更多分組等)運行相同的XSLT:

<?xml version="1.0" encoding="utf-8"?>
<Rootnode>
  <Properties Attribute="xxx">
    <Type>1</Type>
    <Size>10</Size>
  </Properties>
  <Other>
    <blah>h</blah>
  </Other>
  <Other2>
    <blah>h</blah>
  </Other2>
  <Properties Attribute="yyy">
    <xType>5</xType>
    <xSize>10</xSize>
  </Properties>
  <Items>
    <Item4>8</Item4>
  </Items>
  <Items place="US">
    <Item9>8</Item9>
  </Items>
  <Items>
    <Item1>8</Item1>
  </Items>
  <Properties Attribute2="xxx">
    <zType>1</zType>
    <zSize>10</zSize>
  </Properties>
  <Properties Attribute="xxx">
    <elephantType>5</elephantType>
    <elephantSize>15</elephantSize>
  </Properties>
  <Items place="UK">
    <Item1>8</Item1>
  </Items>
</Rootnode>

...再一次,我認為是正確的答案產生了:

<?xml version="1.0"?>
<Rootnode>
  <Properties Attribute="xxx">
    <Size>10</Size>
    <Type>1</Type>
    <elephantSize>15</elephantSize>
    <elephantType>5</elephantType>
  </Properties>
  <Properties Attribute="yyy">
    <xSize>10</xSize>
    <xType>5</xType>
  </Properties>
  <Properties Attribute2="xxx">
    <zSize>10</zSize>
    <zType>1</zType>
  </Properties>
  <Items>
    <Item1>8</Item1>
    <Item4>8</Item4>
  </Items>
  <Items place="UK">
    <Item1>8</Item1>
  </Items>
  <Items place="US">
    <Item9>8</Item9>
  </Items>
</Rootnode>

假設:

  • 我假設每個<Properties><Items>元素都只有一個屬性,並且它應該是分組確定器。
  • 如果以上情況都不成立,那么我至少認為該元素的第一個屬性應該是分組確定器。

說明:

  1. 因為這是XSLT 1.0解決方案, Muenchian Grouping是在唯一選擇器下對節點和屬性進行分組時的日常工作。 因此,我們定義了兩個鍵:一個用於<Properties>元素,另一個用於<Items>元素。

  2. 第一個模板是Identity Transform -其工作是將所有文檔從源文檔按原樣輸出到結果文檔。

  3. 第二個模板與<Rootnode>元素匹配。 指示僅將模板應用於首先出現在各自鍵中的那些<Properties><Items>元素。 這具有僅處理唯一元素的預期效果(基於它們的第一個屬性的名稱和值)。

    指定<xsl:apply-templates>元素后,請注意,在兩種情況下,都將指示該屬性按相同的屬性名稱/值對對結果進行排序。

    請注意,每個<xsl:apply-templates>元素都有一個參數(通過<xsl:with-param> )。 正如您將看到的,用於處理<Properties><Items>元素的代碼幾乎是相同的。 唯一的區別是我們從中獲取結果的關鍵。 因此,我選擇將該邏輯合並到第三個模板中,並通過此參數說明可變性。

  4. 第三個模板匹配<Properties><Items>元素。 對於每個節點,將復制原始節點(及其屬性)。 最后,將模板應用於此元素的所有子元素([此時,基於子元素本身的名稱]進行了適當的排序)。

如果您已經有了東西而不是一無所有,那么您將更有可能獲得幫助。 首先,創建一個與Properties和Items相匹配的模板( match="Properties | Items" ),其內容只是復制匹配的元素: <xsl:copy-of select="." /> <xsl:copy-of select="." />

這將為您顯示一些工作代碼。

我建議的下一步是發布所需輸出的樣本,以及XSLT代碼給出的實際輸出。

這將使人們在回答您的問題時彌合的差距大大縮小。

暫無
暫無

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

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