#xml #xslt
#xml #xslt
Вопрос:
У меня есть простой xml, который я выравниваю (элементы к атрибутам)
ввод xml
<?xml version="1.0" ?>
<queryResponse type="Clients" rootUrl="https://10.130.0.192/webacs/api/v1/data" requestUrl="https://10.30.0.192/webacs/api/v1/data/Clients?.full=trueamp;amp;.firstResult=0amp;amp;.maxResults=1000" responseType="listEntityInstances" count="349" first="0" last="348">
<entity url="https://10.130.0.192/webacs/api/v1/data/Clients/621621" type="Clients" dtoType="clientsDTO">
<clientsDTO id="621621" displayName="621621">
<associationTime>1474746255456</associationTime>
<clientInterface>GigabitEthernet1/0/16</clientInterface>
<connectionType>WIRED</connectionType>
<deviceIpAddress>10.1.1.254</deviceIpAddress>
<deviceName>stack</deviceName>
<deviceType>Unknown</deviceType>
<ipAddress>10.30.0.106</ipAddress>
<location>Unknown</location>
<macAddress>macaddress</macAddress>
<protocol>DOT3</protocol>
<securityPolicyStatus>PASSED</securityPolicyStatus>
<status>ASSOCIATED</status>
<updateTime>1474746256758</updateTime>
<vendor>Netapp</vendor>
<vlan>vlan_300_server</vlan>
<vlanId>300</vlanId>
</clientsDTO>
</entity>
</queryResponse>
xslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="queryResponse">
<Data>
<xsl:apply-templates/>
</Data>
</xsl:template>
<xsl:template match="clientsDTO">
<Client>
<xsl:for-each select="descendant::*[not(*)]">
<xsl:attribute name="{name()}">
<xsl:value-of select="text()"/>
</xsl:attribute>
</xsl:for-each>
</Client>
</xsl:template>
</xsl:stylesheet>
который отлично работает и предоставляет мне мой сглаженный выходной xml.
Теперь с этим XSLT я хотел бы добавить еще одну вещь. Элементы clientInterface и DeviceName должны быть (дополнительно) объединены в качестве нового атрибута.
Есть идеи о том, как этого добиться?
Обновить:
Мой текущий выходной xml выглядит следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Client associationTime="1474746255456" clientInterface="GigabitEthernet1/0/16" connectionType="WIRED" deviceIpAddress="10.1.1.254" deviceName="stack" deviceType="Unknown" ipAddress="10.130.0.106" location="Unknown" macAddress="macaddress" protocol="DOT3" securityPolicyStatus="PASSED" status="ASSOCIATED" updateTime="1474746256758" vendor="Netapp" vlan="vlan_300_server" vlanId="300" />
</Data>
Теперь внутри этого » я хотел бы иметь новый атрибут, который объединяет DeviceName и clientInterface, что приводит к:
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Client **deviceId="stack_GigabitEthernet1/0/16"**associationTime="1474746255456" clientInterface="GigabitEthernet1/0/16" connectionType="WIRED" deviceIpAddress="10.1.1.254" deviceName="stack" deviceType="Unknown" ipAddress="10.130.0.106" location="Unknown" macAddress="macaddress" protocol="DOT3" securityPolicyStatus="PASSED" status="ASSOCIATED" updateTime="1474746256758" vendor="Netapp" vlan="vlan_300_server" vlanId="300" />
</Data>
Комментарии:
1. Возможно, вы также можете добавить желаемый выходной xml в свой вопрос для большей ясности.
2. Добавлено то, что я получил до сих пор, и чего я хотел бы достичь. новый элемент находится в ** и называется DeviceID
Ответ №1:
Вы могли бы сделать:
<xsl:template match="clientsDTO">
<Client>
<xsl:attribute name="deviceId">
<xsl:value-of select="deviceName"/>
<xsl:text>_</xsl:text>
<xsl:value-of select="clientInterface"/>
</xsl:attribute>
<xsl:for-each select="*[not(*)]">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
</Client>
</xsl:template>
Примечание: использование descendant
оси неэффективно — и в вашем случае не нужно.
Комментарии:
1. Идеально! Кажется, делает именно то, что я хочу. Потомок действительно все еще оставался остатком от предыдущего преобразования (где это имело смысл), но его можно удалить здесь.