gpt4 book ai didi

xml - 使用 XSLT 创建基于双重条件的元素

转载 作者:行者123 更新时间:2023-12-03 17:26:31 24 4
gpt4 key购买 nike

为了创建我想要的元素,我很难理解我需要的语法。全新的 XML/XSLT,不确定这是否是正确的方法。

我正在尝试将我的 XML 数据文件解析为以元素为中心,以便我可以将数据格式化为访问数据库中的可读结构。

我试图根据两个条件从元素内部提取数据值。

数据位于名为“”的元素内阅读 '并且数据被标记为'值'。 'Reading' 元素上方是名为' 的定义元素。消费规范 '。

我要测试的是当前的测量单位( UOM )'消费规范 ' 已打开,然后,测试另一个名为 ' 的属性头桶 ',它的值是 'TierA'、'TierB'/C/D 或 Total。 计量单位 可以保存“kWh、kW、kVAh 或 kVA”。我正在尝试布置第一个,因为我将重复此测试以制作每个层(A 到 D)和总计的元素。 (尽量给出清楚的解释)

目前我正在尝试使用 xsl:for-each 选择阅读上方的 ConsumptionSpec,然后使用 xsl:当测试计量单位 头桶 分开。测试后,我创建了一个元素,并尝试提取当前 的值阅读 元素。

这是我的 XML 的摘录,因此您可以看到我在测试过程中尝试单步执行的值。

<MeterReadings Irn="Null" Source="Remote" SourceName="Null" SourceIrn="Null" Initiator="Schedule" Purpose="Null" CollectionTime="2017-04-01 09:00:00" >
<Meter MeterIrn="Null" MeterName="Null" IsActive="true" SerialNumber="Null" MeterType="A3_ILN" Description="" InstallDate="2017-01-21 05:00:00" RemovalDate="" AccountIdent="Null" AccountName="" SdpIdent="" Location="Null" TimeZoneIndex="Null" Timezone="Null" TimeZoneOffset="300" ObservesDaylightSavings="false" MediaType="900 MHz" />

<ReadingQualityIndicator Name="Tamper Alert" Value="true" />

<ConsumptionData >

<ConsumptionSpec UOM="kWh" Direction="Delivered" TouBucket="Total" MeasurementPeriod="Current" Multiplier="1" />

<Reading TimeStamp="2017-04-01 03:08:00" Value="902" />

</ConsumptionData>

<ConsumptionData >

<ConsumptionSpec UOM="kWh" Direction="Delivered" TouBucket="TierA" MeasurementPeriod="Current" Multiplier="1" />

<Reading TimeStamp="2017-04-01 03:08:00" Value="0" />

</ConsumptionData>

<ConsumptionData >

<ConsumptionSpec UOM="kWh" Direction="Delivered" TouBucket="TierB" MeasurementPeriod="Current" Multiplier="1" />

<Reading TimeStamp="2017-04-01 03:08:00" Value="0" />

</ConsumptionData>

<ConsumptionData >

<ConsumptionSpec UOM="kWh" Direction="Delivered" TouBucket="TierC" MeasurementPeriod="Current" Multiplier="1" />

<Reading TimeStamp="2017-04-01 03:08:00" Value="902" />

</ConsumptionData>

<ConsumptionData >

<ConsumptionSpec UOM="kWh" Direction="Delivered" TouBucket="TierD" MeasurementPeriod="Current" Multiplier="1" />

<Reading TimeStamp="2017-04-01 03:08:00" Value="0" />

</ConsumptionData>

这是我当前的 XSLT
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>

<!-- BY DEFAULT, elements and text nodes are copied,
and elements' attributes and contents are transformed as child nodes
of the output element -->
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<!-- By default, attributes are transformed to elements -->
<xsl:template match="@*">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>


<!-- Certain elements have only their contents transformed -->
<xsl:template match="
Meter | Status | ConsumptionData |
Statuses | MaxDemandData | MaxDemandSpec |
InstrumentationValue | IntervalData | IntervalSpec">
<!-- no xsl:copy, and attribute children, if any, are ignored -->
<xsl:apply-templates select="@* | node()"/>
</xsl:template>


<!--
Applies an extra element tag to the selected match


and pulls the value from the MeterReading ancestor it's
tagged under.
-->

<xsl:template match="Reading">

<xsl:copy>

<xsl:element name="MeterReadingIRN">
<xsl:value-of select="ancestor::MeterReadings/@Irn"/>
</xsl:element>

<!--
Trying to get into the ConsumptionSpec tag it's related to,
then test what the unit of measurement is (UOM),
and then test what 'TouBucket' it is a part of (TierA/B/C/D or Total),
and THEN create a new element so that I can hold the 'value' that is inside
the Reading element, so that it will be referenced to that specific UOM.
-->
<xsl:for-each select="ancestor::ConsumptionSpec">
<xsl:choose>
<xsl:when test="@UOM='kWh'">
<xsl:when test="@TouBucket='Total'">

<xsl:element name="kWhTotal">
<xsl:value-of select="Reading/@Value"/>
</xsl:element>

</xsl:when>
</xsl:when>
<!-- Not sure how I can make my otherwise into a useful element here -->
<xsl:otherwise>

<xsl:element name="BlankTest">
<xsl:value-of select="ancestor::MeterReadings/@Irn"/>
</xsl:element>

</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="Channel">
<xsl:copy>
<xsl:element name="MeterReadingIRN">
<xsl:value-of select="ancestor::MeterReadings/@Irn"/>
</xsl:element>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

感谢您提出任何和所有建议,在复活节周末的大部分时间里,我一直在努力反对!让我知道我是否可以提供更多信息以使其更易于理解。

最佳答案

而不是试图嵌套 xsl:when语句,这是不允许的,你想要的语法是这样的......

<xsl:when test="@UOM='kWh' and @TouBucket='Total'">

但是,在使用 xsl:for-each 之前,您确实会遇到问题。
<xsl:for-each select="ancestor::ConsumptionSpec">

您目前正在匹配 Reading此时元素,因此您当前将定位在该元素上。 ConsumptionSpec不是当前 Reading 的祖先元素虽然。它是一个 sibling 。
<ConsumptionData >
<ConsumptionSpec UOM="kWh" Direction="Delivered" TouBucket="TierA" MeasurementPeriod="Current" Multiplier="1" />
<Reading TimeStamp="2017-04-01 03:08:00" Value="0" />
</ConsumptionData>

ConsumptionData那是两个 ConsumptionSpec 的父级和 Reading这里。

另外,请注意 <xsl:for-each select="ancestor::ConsumptionSpec">确实选择了一个元素,它会改变你的位置 ReadingConsumptionSpec .

我假设你只有一个 ConsumptionSpec根据 Reading ?在这种情况下,使用变量可能会更好。

试试这个模板匹配:
<xsl:template match="Reading">
<xsl:copy>
<MeterReadingIRN>
<xsl:value-of select="ancestor::MeterReadings/@Irn"/>
</MeterReadingIRN>
<xsl:variable name="spec" select="../ConsumptionSpec" />
<xsl:choose>
<xsl:when test="$spec/@UOM='kWh' and $spec/@TouBucket='Total'">
<kWhTotal>
<xsl:value-of select="@Value"/>
</kWhTotal>
</xsl:when>
<xsl:otherwise>
<BlankTest>
<xsl:value-of select="ancestor::MeterReadings/@Irn"/>
</BlankTest>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

注意,没有真正需要使用 xsl:element在这种情况下创建一个新元素。只需直接写出您要创建的元素即可。

语法 ..在 XPath 中表示选择父级,所以 ../ConsumptionSpec将选择 ConsumptionSpec那是与 Reading 相同父级的子级.

关于xml - 使用 XSLT 创建基于双重条件的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43475843/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com