2012-02-28 15 views
5

Một câu hỏi khá nghiêm túc, hoặc vì vậy tôi nghĩ ...Xpath làm cách nào để nhận được tổng chiều dài chuỗi của tất cả thuộc tính trên con của cha mẹ?

select="../Store" trả về một nút chứa tất cả các nút tôi cần. Sau đó, tôi cần phải tính toán độ dài chuỗi của thuộc tính name gắn liền với nút Store.

Tôi đã nghĩ nó sẽ là: select="string-length(../Store/@name)" nhưng điều này chỉ trả về độ dài chuỗi của nút đầu tiên.

Bất kỳ ý tưởng nào?

+0

XML mẫu xin vui lòng .. –

+1

Chúng tôi không biết phần tử 'Store' chứa gì và chứa bao nhiêu thuộc tính ... !! –

+0

Tôi chỉ quan tâm đến độ dài chuỗi của thuộc tính @name. –

Trả lời

8
<xsl:variable name="StoreNames"> 
    <xsl:for-each select="../Store"> 
    <xsl:value-of select="@name"/> 
    </xsl:for-each> 
</xsl:variable> 

<xsl:value-of select="string-length($StoreNames)" /> 

Đẹp và dễ dàng!

3
sum(../Store/@name/string-length()) 
+0

Điều này dường như không hoạt động? "Đã tìm thấy mã thông báo dự kiến ​​')' được tìm thấy ..." –

+0

Cần. Bạn đã sử dụng nó như thế nào? – flyx

+0

@flyx, tôi đoán OP đang có XSLT 1.0 :) –

3

tôi giả XML đầu vào của bạn:

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <Store name="data1"/> 
    <Store name="data2"/> 
    <Store name="data3"/> 
    <Store name="data4"/> 
    <Store name="data55"/> 
</root> 

Đây là mã XSLT:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
> 
    <xsl:output method="text" indent="yes"/> 
    <xsl:template match="/"> 
    <xsl:apply-templates select="node()"/> 
    </xsl:template> 

    <xsl:template match="Store[1]"> 
     <xsl:call-template name="calclength"/> 
    </xsl:template> 
    <xsl:template name="calclength"> 
    <xsl:param name="lengthsum" select="'0'"/> 
    <xsl:variable name="newlengthsum" select="string-length(@name/.) + $lengthsum"/> 
    <xsl:for-each select="following-sibling::Store[1]"> 
     <xsl:call-template name="calclength"> 
     <xsl:with-param name="lengthsum" select="$newlengthsum"/> 
     </xsl:call-template> 
    </xsl:for-each> 
    <xsl:if test="not(following-sibling::Store[1])"> 
     LengthOfNameAttrs: 
     <xsl:value-of select="$newlengthsum"/> 

     Averagelength: 
     <xsl:variable name="count" select="count(../Store)"/> 
     <xsl:value-of select="$newlengthsum div $count"/> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

Output là:

LengthOfNameAttrs: 
    26 

    Averagelength: 
    5.2 

Bạn cần phải gọi mẫu calclength chỉ chođầu tiênnút .. tức là, Store[1] nó sẽ tính toán và trả về tổng của tất cả sibling-nodes .. chỉ cần sử dụng các tệp XML và XSLT này và thực thi chúng. Hãy cho tôi biết nếu bạn cần bất kỳ sự trợ giúp nào trong phần calling the template. Nó có thể được chỉnh sửa theo quy định.

8

Trong XPath 2.0 sử dụng một biểu thức duy nhất như này:

sum(../Store/@name/string-length(.)) 

này không thể được thực hiện với một XPath đơn 1.0 biểu (một chức năng như một bước vị trí không được phép), do đó một số giúp đỡ của ngôn ngữ lưu trữ là cần thiết.

Ví dụ, nếu ngôn ngữ hosting là XSLT:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

<xsl:template match="/*"> 
    <xsl:apply-templates select="Store[@name][1]"/> 
</xsl:template> 

<xsl:template match="Store[@name]"> 
    <xsl:param name="vAccum" select="0"/> 

    <xsl:value-of select="$vAccum + string-length(@name)"/> 
</xsl:template> 

<xsl:template match="Store[@name and following-sibling::Store/@name]"> 
    <xsl:param name="vAccum" select="0"/> 

    <xsl:apply-templates select="following-sibling::Store[@name][1]"> 
    <xsl:with-param name="vAccum" select="$vAccum + string-length(@name)"/> 
    </xsl:apply-templates> 
</xsl:template> 
</xsl:stylesheet> 

khi chuyển đổi này được áp dụng trên các tài liệu XML sau:

<root> 
    <Store name="ab"/> 
    <Store name="cde"/> 
    <Store name="fgh"/> 
    <Store name="ijklmn"/> 
    <Store name="opr"/> 
</root> 

các truy nã, kết quả đúng là được sản xuất:

+0

tuyệt vời !! .. (giải pháp xslt 1.0) –

+0

mã của flyx không hoạt động cho OP, vì vậy tôi cho rằng anh ta đang làm việc với bộ vi xử lý XSLT 1.0 .. –

+0

@ infantprogrammer'Aravind ': Nếu bạn thấy điều này thật tuyệt vời, bạn cần phải xem xét FXSL: http://fxsl.sf.net :) –

Các vấn đề liên quan