#xslt #biztalk
#xslt #biztalk
Вопрос:
У меня есть XML-схема, из которой мне нужно извлекать значения, но мне не очень везет.
Исходная схема такова:
<Reading>
<State>
<StateValues>
<Name>
<Value>
</StateValues>
</State>
<Reading>
Примером XML может быть:
<Reading>
<State>
<StateValues>
<Name>Reading1</Name>
<Value>1234</Value>
</StateValues>
<StateValues>
<Name>Reading2</Name>
<Value>2345</Value>
</StateValues>
</State>
<State>
<StateValues>
<Name>Reading3</Name>
<Value>4321</Value>
</StateValues>
</State>
<Reading>
Мне нужен результат, который:
<Readings>
<Reading1>1234</Reading1>
<Reading2>2345</Reading2>
<Reading3>4321</Reading3>
</Readings>
У меня нет контроля над схемами.
Я пытался использовать a xsl:foreach
с xsl:if
, который проверяет имя, но я просто получаю первое значение, повторяемое 3 раза. Есть какие-нибудь советы? Я пытался разобраться в этом в течение 2 дней, и я не эксперт по XSLT…
Спасибо. РЕДАКТИРОВАТЬ: Извините, что не разместил мой XSLT. Я перепробовал несколько версий и не думал, что это будет полезно. Вот оно:
Цитата из блока
<xsl:element name="ns0:Readings">
<xsl:element name="ns0:Current">
<xsl:for-each select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']">
<xsl:choose>
<xsl:when test="Name='TOTAL'">
<xsl:element name="ns0:Total">
<xsl:value-of select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()='Total'" />
</xsl:element>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()='Reading1'">
<xsl:element name="ns0:Reading1">
<xsl:value-of select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()" />
</xsl:element>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text() = 'Reading2'">
<xsl:element name="ns0:Reading2">
<xsl:value-of select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()" />
</xsl:element>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text() = 'Reading3'">
<xsl:element name="ns0:Reading3">
<xsl:value-of select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()" />
</xsl:element>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text() = 'Reading4'">
<xsl:element name="ns0:Reading4">
<xsl:value-of select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()" />
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:element>
</xsl:element>
Комментарии:
1. Что это за XSLT, который вы пытаетесь использовать?
2. Вы кое-что неправильно поняли в спецификации. Если бы вы показали нам свой код, мы могли бы рассказать вам, где вы ошиблись, что было бы гораздо полезнее, чем просто предоставить вам решение.
3. Я отклонил ваш вопрос. Если вы пытались что-то сделать, и это не удалось, вы должны рассказать нам, что вы пытались и как это не удалось.
4. Извините, что не опубликовал XSLT. Надеюсь, моя правка ответит на любые вопросы. Я пытаюсь использовать это в скриптовом функционале в BizTalk.
Ответ №1:
foreach
и if
обычно являются неправильным подходом в XSLT. Гораздо эффективнее применять шаблоны к шаблонам. В этом случае вы можете использовать два: первый устанавливает корневой элемент и сопоставляет элементы, с которыми вы хотите работать:
<xsl:template match='/'>
<Readings>
<xsl:apply-templates select='Reading/State/StateValues'/>
</Readings>
</xsl:template>
и второе, что вышеуказанное срабатывает при обнаружении соответствия, которое будет выполнять основную работу. Сложность здесь заключается в динамическом создании элемента, что означает использование {XPath}
синтаксиса для получения имени из входного документа:
<xsl:template match='StateValues'>
<xsl:element name='{Name}'>
<xsl:value-of select='Value' />
</xsl:element>
</xsl:template>
Комментарии:
1. 1 {Name} — Мне нужно было изменить корневое соответствие на <xsl:template match=’/Reading’>
2. Спасибо за ответ. Раньше я узнавал об этом гораздо больше, и у меня это работало. Мы очень ценим вашу помощь.