Có một XSLT tên-của phần tử?


101

Trong XSLT có

<xsl:value-of select="expression"/>

để nhận giá trị của một phần tử, nhưng có điều gì đó để chọn tên thẻ của phần tử không?

Trong tình huống như thế này:

<person>
  <!-- required stuff -->
  <name>Robert</name>
  <!-- optional stuff, free form for future extension. 
       Using XMLSchema's xsd:any -->
  <profession>programmer</profession>
  <hobby>photography</hobby>
</person>

<xsl:for-each select="person">
   <xsl:tag-of select="."/> : <xsl:value-of select="."/>
</xsl:for-each>

Để có đầu ra như thế này:

name : Robert
profession : programmer
hobby : photography

Tất nhiên XSLT ở trên sẽ không biên dịch vì

 <xsl:tag-of select="expression"/>

không tồn tại. Nhưng làm thế nào điều này có thể được thực hiện?


Thẻ phù hợp nhất cho câu hỏi này là XPath. Cả hai chức năng là XPath chức năng tiêu chuẩn và có thể được sử dụng trong một biểu thức XPath trong bối cảnh bất kỳ ngôn ngữ lưu trữ (C #, XSLT, XQuery, ...) Xin vui lòng, lại thẻ
Dimitre Novatchev

Văn bản này: "Trong XSLT có <xsd: value-of select =" expression "/>" - có lỗi. Tiền tố thường được sử dụng cho các lệnh XSLT là "xsl". Thông thường khi sử dụng Lược đồ XML, chúng ta sử dụng tiền tố "xsd" hoặc "xs". Xin vui lòng, chính xác.
Dimitre Novatchev

Câu trả lời:


156

Điều này sẽ cung cấp cho bạn tên phần tử hiện tại (tên thẻ)

<xsl:value-of select ="name(.)"/>

OP-Edit: Điều này cũng sẽ thực hiện thủ thuật:

<xsl:value-of select ="local-name()"/>

12
local-name là những gì bạn muốn 9 lần trong số 10
annakata

20
local-name là không gian tên không có, đây là lý do tại sao nó thường tốt hơn.
Jon W

102

Không ai đã chỉ ra sự khác biệt tinh tế trong ngữ nghĩa của các chức năng name()local-name().

  • name(someNode) trả về tên đầy đủ của nút và bao gồm tiền tố và dấu hai chấm trong trường hợp nút là một phần tử hoặc một thuộc tính.
  • local-name(someNode) chỉ trả về tên cục bộ của nút và không bao gồm tiền tố và dấu hai chấm trong trường hợp nút là một phần tử hoặc một thuộc tính.

Do đó, trong trường hợp một tên có thể thuộc hai không gian tên khác nhau, người ta phải sử dụng name()hàm để các tên này vẫn được phân biệt.

Và, BTW, có thể chỉ định cả hai hàm mà không cần bất kỳ đối số nào :

name() là chữ viết tắt của name(.)

local-name() là chữ viết tắt của local-name(.)

Cuối cùng , hãy nhớ rằng không chỉ các phần tử và thuộc tính có tên, hai hàm này cũng có thể được sử dụng trên PI và chúng giống hệt nhau).


15
<xsl:for-each select="person">
  <xsl:for-each select="*">
    <xsl:value-of select="local-name()"/> : <xsl:value-of select="."/>
  </xsl:for-each>  
</xsl:for-each>

Như một phương pháp hay, luôn sử dụng normalize-space () khi nhận giá trị-của nút <xsl: value-of select = "normalize-space (.)" /> Thao tác này sẽ cắt bớt các khoảng trắng thừa
SO Người dùng

Việc chuẩn hóa / sanitisation như vậy sẽ chỉ cần thiết nếu nó chưa được xử lý ở giai đoạn thu thập đầu vào. Làm điều đó sau đó tiết kiệm phải làm điều đó vào thời gian truy cập, thường là thường xuyên hơn nhiều. Người ta sẽ làm điều đó trước khi thêm vào RDB và tài liệu xml chỉ là một cơ sở dữ liệu khác.
Patanjali

9

Đối với những người quan tâm, không có:

<xsl:tag-of select="."/>

Tuy nhiên, bạn có thể tạo lại thẻ / phần tử bằng cách:

<xsl:element name="{local-name()}">
  <xsl:value-of select="substring(.,1,3)"/>
</xsl:element>

Điều này rất hữu ích trong mẫu xslt, ví dụ như xử lý các giá trị dữ liệu định dạng cho rất nhiều phần tử khác nhau. Khi bạn không biết tên của phần tử đang được làm việc và bạn vẫn có thể xuất phần tử tương tự và sửa đổi giá trị nếu cần.


6
<xsl:value-of select="name(.)" /> : <xsl:value-of select="."/>

Vậy tại sao điều này lại bị bỏ phiếu? Granted có thể đã đề cập đến local-name () nếu bạn cũng không muốn không gian tên, nhưng nó sẽ hữu ích cho cộng đồng rộng lớn hơn để giải thích tại sao điều này không hoạt động.
Rowland Shaw

Có lẽ, nó không thể chuyển đổi XML đã cho. tên (.) sẽ là "người" trong trường hợp này. nó phải là "tên", "nghề nghiệp" và "sở thích".
Ray Lu

@CodeMelt Tại sao sau đó bạn không tán thành câu trả lời được chấp nhận? Nó tốt, nhưng thậm chí còn ít cụ thể hơn cái này. Tôi đã bầu chọn câu trả lời của Rowland Shaw vì nó cung cấp câu trả lời cho câu hỏi. Plese, downvote chỉ khi một aswer chứa sai thông tin, không chính xác hoặc gây hiểu lầm
Dimitre Novatchev

4
Cố định rằng chi tiết nhỏ - cá nhân tôi, tôi nghĩ rằng mọi người nên giải thích tại sao một cái gì đó được downvoted, vì nó giúp giải thích những kiến thức tập thể ...
Rowland Shaw

Danh tiếng của chúng tôi có thể thu hút sự chú ý, nhưng vì chúng không đảm bảo rằng những gì chúng tôi đã đăng là đáng giá, nên chất lượng đóng góp của chúng tôi mới thực sự quan trọng. Không có lý do nào đưa ra những đóng góp kém chất lượng.
Patanjali
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.