【问题标题】:Build XML file with XSLT to filter on severals childs nodes使用 XSLT 构建 XML 文件以过滤多个子节点
【发布时间】:2017-07-25 14:54:04
【问题描述】:

我有一个来自 ICECAT 的大 xml 文件。我只想获取一些信息。在这个主题的下面filter-dynamically-xml-child-element-with-xslt-with-ssis

现在我有一个像这样的 categoriesList XML 文件:

<ICECAT-interface>
<Response Date="Tue Jul 25 16:00:10 2017" ID="29306604" Request_ID="1500991209" Status="1">
<CategoriesList>
  <Category ID="2597" LowPic="http://images.icecat.biz/img/low_pic/2597-5095.jpg" Score="471102" Searchable="0" ThumbPic="http://images.icecat.biz/thumbs/CAT2597.jpg" UNCATID="43223323" Visible="0">
    <Name ID="1088701" Value="fiber optic adapters" langid="1"/>
    <Name ID="1595015" Value="glasvezeladapters" langid="2"/>
    <Name ID="1088703" Value="adaptateurs de fibres optiques" langid="3"/>
    <Name ID="1245208" Value="LWL-Steckverbinder" langid="4"/>
    <Name ID="1088705" Value="adattatori di fibra ottica" langid="5"/>
    <Name ID="1125574" Value="adaptadores de fibra óptica" langid="6"/>
    <Name ID="1147616" Value="lyslederadapter" langid="7"/>

   <ParentCategory ID="242">
    <Names>
      <Name ID="485" langid="1">networking</Name>
      <Name ID="471244" langid="2">netwerken</Name>
      <Name ID="343986" langid="3">réseaux</Name>
      <Name ID="436999" langid="4">Netzwerke</Name>
      <Name ID="1051724" langid="5">reti</Name>
      <Name ID="1041258" langid="6">redes</Name>
      <Name ID="34261" langid="7">netværk</Name>
      <Name ID="530435" langid="8">сети/коммуникации</Name>

    </Names>
   </ParentCategory>
  </Category>
  <Category ID="4601" LowPic="http://images.icecat.biz/img/low_pic/4601-990.jpg" Score="12621" Searchable="0" ThumbPic="http://images.icecat.biz/thumbs/CAT4601.jpg" UNCATID="56101688" Visible="0">

我需要 Category 节点中的一些属性,例如 IDLowPic... 一些 Name 节点和来自 ParentCategory 节点的 ID

我试过这个 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output  method="xml" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/ICECAT-interface">
        <xsl:apply-templates select="Response"/>
    </xsl:template>

    <xsl:template match="Response">
        <xsl:apply-templates select="CategoriesList"/>
    </xsl:template>

    <xsl:template match="CategoriesList">
        <xsl:copy>
            <xsl:apply-templates select="Category"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Category">
        <xsl:apply-templates select="Name"/>
    </xsl:template>

    <xsl:template match="Name[@langid=1 or @langid=3]">
        <Category>
            <xsl:copy-of select="../@ID|../@LowPic|../@ThumbPic|../@UNCATID||@langid|@Value" />
        </Category>
    </xsl:template>        
</xsl:stylesheet>

我不知道这是否是更好的方法,我没有ParentCategory 节点的ID

更新 对不起,我忘记了我想要的结果

<?xml version="1.0" encoding="utf-8"?>
<Categories>
<Category ID="2597" LowPic="http://images.icecat.biz/img/low_pic/2597-5095.jpg" ThumbPic="http://images.icecat.biz/thumbs/CAT2597.jpg" UNCATID="43223323" name="fiber optic adapters" langid="1" ParentCategory="242"/>
  <Category ID="2597" LowPic="http://images.icecat.biz/img/low_pic/2597-5095.jpg" ThumbPic="http://images.icecat.biz/thumbs/CAT2597.jpg" UNCATID="43223323" name="adaptateurs de fibres optiques" langid="3" ParentCategory="242"/>
 ....

更新 2 我修改了 XSLT 文件,我反转了我的过滤器位置。现在我有了货物记录,只是父类别 id 的湖

【问题讨论】:

  • 你想要的输出是什么样的?
  • 您能否确保您的输出与您的输入完全一致,好吗?您当前的预期输出引用了您输入中没有的文本“其他电话”。如果您输入的 XML 格式正确,也会有所帮助。目前它缺少一些结束标签。谢谢!
  • 我做到了。我在第 1 篇文章中更改示例

标签: xml xslt ssis


【解决方案1】:

您似乎想为每个Name 输出一个Category,其中langid 属性为1 或3。在这种情况下,您需要将条件移动到xsl:apply-templates

<xsl:template match="Category">
    <xsl:apply-templates select="Name[@langid=1 or @langid=3]"/>
</xsl:template>

然后,在匹配 Name 的模板中,您可以像这样为 ParentCategoryId 创建一个属性

 <xsl:attribute name="ParentCategoryId">
    <xsl:value-of select="following-sibling::ParentCategory[1]/@ID" />
 </xsl:attribute>

Name 属性也是如此。

试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output  method="xml" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/ICECAT-interface">
        <xsl:apply-templates select="Response"/>
    </xsl:template>

    <xsl:template match="Response">
        <xsl:apply-templates select="CategoriesList"/>
    </xsl:template>

    <xsl:template match="CategoriesList">
        <xsl:copy>
            <xsl:apply-templates select="Category"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Category">
        <xsl:apply-templates select="Name[@langid=1 or @langid=3]"/>
    </xsl:template>

    <xsl:template match="Name">
        <Category>
            <xsl:copy-of select="../@ID|../@LowPic|../@ThumbPic|../@UNCATID|@langid" />
            <xsl:attribute name="Name">
                <xsl:value-of select="@Value" />
            </xsl:attribute>
            <xsl:attribute name="ParentCategoryId">
              <xsl:value-of select="following-sibling::ParentCategory[1]/@ID" />
            </xsl:attribute>
        </Category>
    </xsl:template>        
</xsl:stylesheet>

注意,您可以使用属性值模板来简化Name 模板

<xsl:template match="Name">
    <Category Name="{@Value}" ParentCategoryId="{following-sibling::ParentCategory[1]/@ID}">
        <xsl:copy-of select="../@ID|../@LowPic|../@ThumbPic|../@UNCATID|@langid" />
    </Category>
</xsl:template>  

【讨论】:

  • 超级,但我不知道 parentcategory 是否会一直在后面,那么 follow-sibling 可能还不够。然后我替换为 ''
  • 我在空值上添加过滤器:'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
  • 2019-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多