#xml #xslt #xml-namespaces
#xml #xslt #xml-пространства имен
Вопрос:
Если у меня есть этот xml:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope>
<m:RgWsPublicFirmActRtUser>
<m:firmActDescr>ΑΛΛΟ ΛΙΑΝΙΚΟ ΕΜΠΟΡΙΟ ΣΕ ΜΗ ΕΞΕΙΔΙΚΕΥΜΕΝΑ ΚΑΤΑΣΤΗΜΑΤΑ</m:firmActDescr>
<m:firmActKind>2</m:firmActKind>
<m:firmActKindDescr>ΔΕΥΤΕΡΕΥΟΥΣΑ</m:firmActKindDescr>
<m:firmActCode>47191000</m:firmActCode>
</m:RgWsPublicFirmActRtUser>
<m:RgWsPublicFirmActRtUser>
<m:firmActDescr>ΛΙΑΝΙΚΟ ΕΜΠΟΡΙΟ ΕΙΔΩΝ ΔΩΡΩΝ ΓΕΝΙΚΑ</m:firmActDescr>
<m:firmActKind>2</m:firmActKind>
<m:firmActKindDescr>ΔΕΥΤΕΡΕΥΟΥΣΑ</m:firmActKindDescr>
<m:firmActCode>47191008</m:firmActCode>
</m:RgWsPublicFirmActRtUser>
</env:Envelope>
И я использую этот XSLT:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h3>Δραστηριότητες</h3>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Δραστηριότητα</th>
<th style="text-align:left">Αριθμός δραστηριότητας</th>
<th style="text-align:left">Περιγραφή δραστηριότητας</th>
<th style="text-align:left">Κωδικός δραστηριότητας</th>
</tr>
<xsl:for-each select="Envelope/RgWsPublicFirmActRtUser">
<tr>
<td><xsl:value-of select="firmActDescr"/></td>
<td><xsl:value-of select="firmActKind"/></td>
<td><xsl:value-of select="firmActKindDescr"/></td>
<td><xsl:value-of select="firmActCode"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Все работает нормально, но когда у меня есть пространство имен во входном XML:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m="http://gr/gsis/rgwspublic/RgWsPublic.wsdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
Вместо без пространств имен:
<env:Envelope>
XSLT не будет работать
Моя проблема в том, что XML получен от третьей стороны, и я не могу контролировать содержимое. Мне нужно обработать его как есть. Может быть, я могу заменить большой env:Envelope и маленький env:Envelope внутри серверного процесса, но могу ли я заставить XSLT работать без изменения XML?
Ответ №1:
Чтобы сопоставить элементы пространства имен в XSLT, вы должны объявить префикс пространства имен в таблице стилей для того же URI пространства имен и использовать этот префикс в ваших выражениях XPath:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:m="http://gr/gsis/rgwspublic/RgWsPublic.wsdl">
<xsl:template match="/">
<!-- ... -->
<xsl:for-each select="env:Envelope/m:RgWsPublicFirmActRtUser">
( m:
URI пространства имен взят из вашего комментария). URI пространства имен не обязательно должны быть реальными URL-адресами, которые может получить браузер, они просто обрабатываются как уникальные идентификаторы для пространства имен. Некоторые технологии XML используют идентификаторы «URN» для своих пространств имен (например urn:example:namespace
) вместо URL-адресов http.
Комментарии:
1. url-адрес m <m:rgWsPublicAfmMethodResponse xmlns:m=» gr/ gsis/rgwspublic/RgWsPublic.wsdl «> но странно, что я не могу найти этот тип URL-адреса url