【问题标题】:How to create key value pair inside XSLT and get value using key如何在 XSLT 中创建键值对并使用键获取值
【发布时间】:2016-07-25 13:37:28
【问题描述】:

在 XSLT 内部,我有来自 XML 的状态,并且在对应于该状态时,我有自己的状态代码,我想将其放入转换后的 XML 中。

源 XML:

<states>
<state>New York</state>
<state>California</state>
</states>

预期结果:

<states>
    <state>NY</state>
    <state>CA</state>
</states>

因为我有状态列表,所以我不能使用 whenIf 语句所以他们在 XSLT 1.0 或 2.0 中是否有任何优化的方法来解决这个问题?提前致谢。

【问题讨论】:

  • 您能否通过摘录状态列表(映射)来扩展您的问题?
  • 在 XSLT 2.0 中,您可以将映射表放在样式表中的全局变量中。在纯 1.0 中您无法做到这一点,但许多处理器提供的 exslt:node-set() 函数使之成为可能。

标签: xml xslt


【解决方案1】:

这是您可以查看的一种方式:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://example.com/my">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="state" match="state" use="." />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="state">
    <xsl:copy>
        <xsl:value-of select="key('state', ., document(''))/@code"/>
    </xsl:copy>
</xsl:template>

<my:states>
    <state code="AL">Alabama</state>
    <state code="AK">Alaska</state>
    <state code="AZ">Arizona</state>
    <state code="AR">Arkansas</state>
    <state code="CA">California</state>
    <state code="CO">Colorado</state>
    <state code="CT">Connecticut</state>
    <state code="DE">Delaware</state>
    <state code="DC">District of Columbia</state>
    <state code="FL">Florida</state>
    <state code="GA">Georgia</state>
    <state code="HI">Hawaii</state>
    <state code="ID">Idaho</state>
    <state code="IL">Illinois</state>
    <state code="IN">Indiana</state>
    <state code="IA">Iowa</state>
    <state code="KS">Kansas</state>
    <state code="KY">Kentucky</state>
    <state code="LA">Louisiana</state>
    <state code="ME">Maine</state>
    <state code="MD">Maryland</state>
    <state code="MA">Massachusetts</state>
    <state code="MI">Michigan</state>
    <state code="MN">Minnesota</state>
    <state code="MS">Mississippi</state>
    <state code="MO">Missouri</state>
    <state code="MT">Montana</state>
    <state code="NE">Nebraska</state>
    <state code="NV">Nevada</state>
    <state code="NH">New Hampshire</state>
    <state code="NJ">New Jersey</state>
    <state code="NM">New Mexico</state>
    <state code="NY">New York</state>
    <state code="NC">North Carolina</state>
    <state code="ND">North Dakota</state>
    <state code="OH">Ohio</state>
    <state code="OK">Oklahoma</state>
    <state code="OR">Oregon</state>
    <state code="PA">Pennsylvania</state>
    <state code="RI">Rhode Island</state>
    <state code="SC">South Carolina</state>
    <state code="SD">South Dakota</state>
    <state code="TN">Tennessee</state>
    <state code="TX">Texas</state>
    <state code="UT">Utah</state>
    <state code="VT">Vermont</state>
    <state code="VA">Virginia</state>
    <state code="WA">Washington</state>
    <state code="WV">West Virginia</state>
    <state code="WI">Wisconsin</state>
    <state code="WY">Wyoming</state>
</my:states>

</xsl:stylesheet>

如果您愿意,可以将状态列表及其代码放在外部 XML 文档中并从那里查找。

因为我有状态列表,所以我不能使用 when 或 If 语句

实际上,使用xsl:choose 也可以。

【讨论】:

  • 当我尝试使用您的 xslt 进行转换时,它会出现以下错误。错误:org.xml.sax.SAXParseException; systemId:文件:/base/data/home/apps/s~xslttest-hrd2/5.391785634117992591/;行号:1;列号:1;序言中不能有内容。我正在使用xslttest.appspot.com 进行转换另一件事我可以将上述模板调用到我的另一个模板吗?
  • 您不能使用在线 XSLT 服务来测试它,因为它需要 document() 函数找到一个实际的 XSLT 文件。
  • @JyotishSingh 你的问题没有回答吗?
【解决方案2】:

您可以在映射中包含外部文件并访问映射。我使用“b1.xml”作为文件名。它将全名替换为短名。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:variable name="StateMap" select="document('b1.xml')/StateMapping" />

  <xsl:template match="states">
    <states>        
      <xsl:apply-templates select="state" />
    </states>
  </xsl:template>

  <xsl:template match="state">
    <xsl:variable name="toMap" select="text()" />
    <state><xsl:value-of select="$StateMap/Map[@name = $toMap]" /></state>
  </xsl:template>

</xsl:stylesheet>

应该用自己的替换的外部映射文件是:

<?xml version="1.0"?>
<StateMapping>
  <Map name="New York">NY</Map>
  <Map name="California">CA</Map>
</StateMapping>

输出为:

<?xml version="1.0"?>
<states>
  <state>NY</state>
  <state>CA</state>
</states>

【讨论】:

  • 对不起,我不能使用任何外部文件。
  • 您的外部文件中的状态列表不是像您的问题中描述的那样吗?
  • 不,我的意思是我的列表应该在 XSLT 中。
  • 那么您必须在 XSLT 中创建一个data island。在顶部添加命名空间xmlns:data="http://...whatever",并包含外部映射文件,在此示例中将顶级元素的命名空间替换为&lt;data:StateMapping&gt;。然后将变量中的表达式替换为document('')/data:StateMapping
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多