2014-04-14 34 views
0

我有這樣的樹:Xpath2.0選擇字符串的第一個和最後一次出現與迭代

<Events> 
<Properties> 
    <Property Descriptor=100>1378314022</Property> 
    <Property Descriptor=200>ABC1234</Property> 
</Properties> 
<Properties> 
    <Property Descriptor=100>1378314023</Property> 
    <Property Descriptor=200>ABC1234</Property> 
</Properties> 
<Properties> 
    <Property Descriptor=100>1378314024</Property> 
    <Property Descriptor=200>ABC1234</Property> 
</Properties> 
<Properties> 
    <Property Descriptor=100>1378314022</Property> 
    <Property Descriptor=200>123456</Property> 
</Properties> 
<Properties> 
    <Property Descriptor=100>1378314023</Property> 
    <Property Descriptor=200>123456</Property> 
</Properties> 
<Properties> 
    <Property Descriptor=100>1378314024</Property> 
    <Property Descriptor=200>123456</Property> 
</Properties> 

</Events> 

我在這個級別迭代:Events/Properties

我怎麼能只有首次和最後出現每個Property Descriptor = 200及其各自Property Descriptor = 100

我試過到目前爲止:

  • 迭代:Events/Properties
  • 選擇: Property[@Descriptor=200])[last()] or Property[@Descriptor=200])[first()]

,但沒有成功。

輸出應該是這樣的[我展示它在HTML中,在迭代行級]:

P100  | P200 
1378314022 | ABC1234 
1378314024 | ABC1234 
1378314022 | 123456 
1378314024 | 123456 

回答

3

在XSLT 2.0中,對於for-each-group這很容易,按200值進行分組並取每個組的第一個和最後一個成員。但在純XPath(而非XSLT)中,您需要側重思考。

如果組始終連續因爲你已經在這裏顯示(即所有ABC1234條目是彼此相鄰,並且所有的123456條目是彼此相鄰),則將此歸結爲想每一個Properties元素P,它沒有緊接着的前面的緊接在兄弟姐妹之後Properties元素與200值相同P。即要迭代

Events/Properties[not(
    (
    Property[@Descriptor="200"] = 
    preceding-sibling::Properties[1]/Property[@Descriptor="200"] 
) and (
    Property[@Descriptor="200"] = 
    following-sibling::Properties[1]/Property[@Descriptor="200"] 
) 
)] 

,然後選擇的從每個所得Properties元素Property[@Descriptor="100"]Property[@Descriptor="200"]

您已將您的問題標記爲「xpath-2.0」,但此表達式在XPath 1.0中也有效。

+0

感謝您的優雅的解決方案和詳細的解釋。我已經應用*** Events/Properties [屬性[@描述符=「200」])返回(先前 - 兄弟::屬性[1] [屬性[@描述符=「200」] = $ me],以下 - 兄弟::屬性[1] [屬性[@描述=「200」] = $我]))!= 2] ***到我的應用程序,但迭​​代似乎沒有工作。事件之前有節點,但我將它們添加到迭代中。我可以做嗎? –

+0

我也試過*** // Events/Properties [count(for $ me in(Property [@ Descriptor =「200」])return(preceding-sibling :: Properties [1] [Property [@ Descriptor =「200」 ] = $ me],以下 - 兄弟::屬性[1] [屬性[@描述=「200」] = $我]))!= 2] ***,它沒有工作。 :( –

+0

@Dalek「沒有工作」 - 你得到了什麼輸出?你得到的比預期的還要多,或者你什麼都沒有得到?真正的文檔是否包含任何命名空間,就好像你需要在你的XPath表達式中,通過綁定適當的前綴來考慮到這一點,具體怎麼做取決於你使用的是什麼工具/庫/編程語言,你在問題中沒有說明。 –

0

我不能完全肯定這回答你正在尋找,但在這裏我會給你兩個例子。其中一個應該可能適合您的需求。

我用下面的輸入XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Events> 
    <Properties> 
     <Property Descriptor="100">1378314022</Property> 
     <Property Descriptor="200">ABC1234</Property> 
     <Property Descriptor="100">MD2356</Property> 
     <Property Descriptor="200">25689</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
    <Properties> 
     <Property Descriptor="100">1378314023</Property> 
     <Property Descriptor="200">ABC1234</Property> 
     <Property Descriptor="100">MD2356</Property> 
     <Property Descriptor="200">25689</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
    <Properties> 
     <Property Descriptor="100">1378314024</Property> 
     <Property Descriptor="200">ABC1234</Property> 
     <Property Descriptor="100">MD2356</Property> 
     <Property Descriptor="200">25689</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
    <Properties> 
     <Property Descriptor="100">1378314022</Property> 
     <Property Descriptor="200">123456</Property> 
     <Property Descriptor="100">MD2356</Property> 
     <Property Descriptor="200">25689</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
    <Properties> 
     <Property Descriptor="100">1378314023</Property> 
     <Property Descriptor="200">123456</Property> 
     <Property Descriptor="100">MD2356</Property> 
     <Property Descriptor="200">25689</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
    <Properties> 
     <Property Descriptor="100">1378314024</Property> 
     <Property Descriptor="200">123456</Property> 
     <Property Descriptor="100">MD2356</Property> 
     <Property Descriptor="200">25689</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
</Events> 

當我使用的下一個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:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Properties"> 
     <xsl:copy> 
      <xsl:apply-templates select="Property[@Descriptor = '100'][1]" /> 
      <xsl:apply-templates select="Property[@Descriptor = '100'][last()]" /> 
      <xsl:apply-templates select="Property[@Descriptor = '200'][1]" /> 
      <xsl:apply-templates select="Property[@Descriptor = '200'][last()]" /> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

這XSLT也有過Properties元素的迭代,即Properties元素中它得到的第一次和最後一次發生的每個提供Descriptor。其結果將是:

<?xml version="1.0" encoding="UTF-8"?> 
<Events> 
    <Properties> 
     <Property Descriptor="100">1378314022</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">ABC1234</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
    <Properties> 
     <Property Descriptor="100">1378314023</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">ABC1234</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
    <Properties> 
     <Property Descriptor="100">1378314024</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">ABC1234</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
    <Properties> 
     <Property Descriptor="100">1378314022</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">123456</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
    <Properties> 
     <Property Descriptor="100">1378314023</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">123456</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
    <Properties> 
     <Property Descriptor="100">1378314024</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">123456</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
</Events> 

如果你想獲得最後的恩在所有Properties的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:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Events"> 
     <xsl:copy> 
      <Properties> 
       <xsl:apply-templates select="(Properties/Property[@Descriptor = '100'])[1]" /> 
       <xsl:apply-templates select="(Properties/Property[@Descriptor = '100'])[last()]" /> 
       <xsl:apply-templates select="(Properties/Property[@Descriptor = '200'])[1]" /> 
       <xsl:apply-templates select="(Properties/Property[@Descriptor = '200'])[last()]" /> 
      </Properties> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

結果將被:

<?xml version="1.0" encoding="UTF-8"?> 
<Events> 
    <Properties> 
     <Property Descriptor="100">1378314022</Property> 
     <Property Descriptor="100">MD75632</Property> 
     <Property Descriptor="200">ABC1234</Property> 
     <Property Descriptor="200">5632</Property> 
    </Properties> 
</Events> 
+0

感謝您的詳細解答!我實際上只使用Xpath來實現這個功能......我必須在Events級別[這是一個XPath表達式]進行迭代,並選擇值[這是另一個XPath表達式]。這也必須是動態的,所以我試圖使用Property [@ Descriptor = 200])[last()]或 Property [@ Descriptor = 200])[first()]。對不起,沒有在問題中說清楚! –

相關問題