【问题标题】:Using XSLT to query and pull data from XML使用 XSLT 从 XML 中查询和提取数据
【发布时间】:2019-01-27 20:55:20
【问题描述】:

我正在尝试使用 XSLT 解决以下问题,但有点卡住了。

我有一个工具的 ID,比如说一把锤子。我需要获取该 ID 变量,将其传递给 XSLT 样式表,使用 XSLT 匹配包含具有该 ID 的工具的 XML 文件中的所有 Task 元素。

所以在一个文档(tasks.xml)中我有以下内容(注意<tool><id>

<data>
         <DMs>
          <task>
            <DMC>TEST-4BX-AG3-00-00-0000-125B-A</DMC>
            <techName>Fixing fence</techName>
            <infoName>Inserting panels</infoName>
            <tools>
              <tool>
                <id>1</id><qty>1</qty>
              </tool>
              <tool>
                <id>4</id><qty>1</qty>
              </tool>
            </tools>
        </task>
    <task>
            <DMC>TEST-4BX-AG3-00-00-0000-125B-A</DMC>
            <techName>Fixing floor</techName>
            <infoName>Install floorboard</infoName>
            <notes>-</notes>
            <tools>
              <tool>
                <id>89</id><qty>1</qty>
              </tool>
              <tool>
                <id>25</id><qty>2</qty>
              </tool>
            </tools>
        </task>
      </DMs>
     </data>

所以假设锤子的 ID 是“1”,我现在需要搜索 Tasks.xml 文件并匹配使用锤子的所有任务。只有具有锤子的任务才应包含在输出中。

这是问题的第一部分。

我还有一个文件Tools.xml,里面包含了所有的工具信息,如下:

<data>
         <tools>
          <tool id="1">
            <toolName>Hammer</toolName>
            <toolPN>345123</toolPN>
            <toolCage>-</toolCage>
          </tool>
          <tool id="2">
            <toolName>Digital Multimeter Set</toolName>
            <toolPN>Fluke Model No. 89IV</toolPN>
            <toolCage>-</toolCage>
          </tool>
          <tool id="3">
            <toolName>Digital Storage Oscilloscope</toolName>
            <toolPN>Tektronix 3052B</toolPN>
            <toolCage>-</toolCage>
          </tool>
          <tool id="4">
            <toolName>Socket set</toolName>
            <toolPN>737828</toolPN>
            <toolCage>-</toolCage>
          </tool>
       </tools>
    </data>

我还需要从 Tools.XML 中提取工具的实际名称和详细信息,以便输出 xml 文件列出工具详细信息,例如名称和部件号等,而不仅仅是 ID。

所以我想要的是这样的输出:

<data>
     <DMs>
      <task>
        <DMC>TEST-4BX-AG3-00-00-0000-125B-A</DMC>
        <techName>Fixing fence</techName>
        <infoName>Inserting panels</infoName>
        <tools>
          <tool id="1">
            <toolName>Hammer</toolName>
            <toolPN>345123</toolPN>
            <toolCage>-</toolCage>
          </tool>
          <tool id="4">
            <toolName>Socket set</toolName>
            <toolPN>737828</toolPN>
            <toolCage>-</toolCage>
          </tool>
        </tools>
    </task>
<task>

我一直在搞乱 XSLT,但无法正确处理。我尝试的一切似乎都从输出中完全删除了工具。

这是我一直在使用 Document() 函数和 XSLT Key 玩过的一些 XSLT,但我真的只是在尝试学习 XSLT 时感到很沮丧。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>

  <xsl:variable name="dataModuleLookupDoc" select="document('C:\TOOLS.xml')"/>

  <xsl:key name="toolIDKey" match="tool" use="@id"/>

  <xsl:template match="task">
    <xsl:apply-templates select="$dataModuleLookupDoc"/>
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="tools"/>

  <xsl:template match="tool">
    <xsl:variable name="toolID" select="@ID"/>
    <xsl:for-each select="$dataModuleLookupDoc">
      <xsl:value-of select="key('toolIDKey',toolID)"/>
    </xsl:for-each>
    <xsl:text> </xsl:text>
    <xsl:apply-templates/>
    <xsl:text>
</xsl:text>
  </xsl:template>

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

【问题讨论】:

    标签: c# xml winforms xslt


    【解决方案1】:

    你想要key('toolIDKey, $toolID) 而不是key('toolIDKey',toolID)。那应该在另一个文档中找到该元素,当然&lt;xsl:value-of select="key('toolIDKey, $toolID)"/&gt; 似乎过于简单,试图“提取工具的实际名称和详细信息”,如果您只是想从另一个文档中复制或推送元素,请使用xsl:copy-of它通过一些带有xsl:apply-templates 的模板来根据需要进行转换。

    【讨论】:

      【解决方案2】:

      试试 xml linq

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Xml;
      using System.Xml.Linq;
      
      namespace ConsoleApplication1
      {
          class Program
          {
              const string FILENAME1 = @"c:\temp\test1.xml";
              const string FILENAME2 = @"c:\temp\test2.xml";
              static void Main(string[] args)
              {
                  XDocument xTools = XDocument.Load(FILENAME2);
      
                  Dictionary<int, Tool> toolsDict = xTools.Descendants("tool")
                      .Select(x => new Tool() {
                          id = (int)x.Attribute("id"),
                          name = (string)x.Element("toolName"),
                          pn = (string)x.Element("toolPN"),
                          cage = (string)x.Element("toolCage")
                      }).GroupBy(x => x.id, y => y)
                      .ToDictionary(x => x.Key, y => y.FirstOrDefault());
      
                  XDocument xTasks = XDocument.Load(FILENAME1);
                  List<XElement> toolTask = xTasks.Descendants("tool").ToList();
                  foreach (XElement tool in toolTask)
                  {
                      int id = (int)tool.Element("id");
                      int qty = (int)tool.Element("qty");
                      if(toolsDict.ContainsKey(id))
                      {
                          Tool idTool = toolsDict[id];
      
                          tool.ReplaceWith(new XElement("tool", new object[] {
                              new XAttribute("id", id),
                              new XAttribute("qty", qty),
                              new XElement("toolName", idTool.name),
                              new XElement("toolPN", idTool.pn),
                              new XElement("toolCage", idTool.cage)
                          }));
                      }
      
                //                 <toolName>Hammer</toolName>
                //  <toolPN>345123</toolPN>
                //  <toolCage>-</toolCage>
                //</tool>
                  }
              }
          }
          public class Tool
          {
              public int id { get;set;}
              public string name { get; set; }
              public string pn { get; set; }
              public string cage { get; set; }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-01-20
        • 2013-08-23
        • 1970-01-01
        • 2015-08-24
        • 1970-01-01
        • 2011-03-30
        • 1970-01-01
        • 2012-12-21
        • 2018-03-02
        相关资源
        最近更新 更多