Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 如何在VB.NET(VS2008)中使用XSLT指定自定义属性排序顺序_Xml_Vb.net_Xslt_Visual Studio 2008 - Fatal编程技术网

Xml 如何在VB.NET(VS2008)中使用XSLT指定自定义属性排序顺序

Xml 如何在VB.NET(VS2008)中使用XSLT指定自定义属性排序顺序,xml,vb.net,xslt,visual-studio-2008,Xml,Vb.net,Xslt,Visual Studio 2008,我有这样一个模式: XML: 我需要它在每次交付中对产品代码进行排序,因此输出为: XML: 产品代码为字母或空白。以下规则适用: 产品代码R应首先出现 产品代码G应最后出现 还有别的事吗 我以前从未在愤怒中使用过XSLT,而且我已经很久没有使用任何VB.NET了,所以为了让某些东西工作起来,我提出了以下建议 Module Module1 Sub Main() ' The document Dim document As String =

我有这样一个模式:

XML:


我需要它在每次交付中对产品代码进行排序,因此输出为:

XML:


产品代码为字母或空白。以下规则适用:

  • 产品代码R应首先出现
  • 产品代码G应最后出现
  • 还有别的事吗
  • 我以前从未在愤怒中使用过XSLT,而且我已经很久没有使用任何VB.NET了,所以为了让某些东西工作起来,我提出了以下建议

    Module Module1
    
        Sub Main()
    
            ' The document
            Dim document As String = "<Shipment> <Destination City='New York'> <Delivery> <Product ProductCode='B' ProductType='THI'></Product> <Product ProductCode='U' ProductType='SIS'></Product> <Product ProductCode='R' ProductType='JUS'></Product> <Product ProductCode='G' ProductType='TMA'></Product> <Product ProductCode='E' ProductType='DEU'></Product> <Product ProductCode='R' ProductType='POK'></Product> </Delivery> </Destination> <Destination City='London'> <Delivery> <Product ProductCode='C' ProductType='MAK'></Product> <Product ProductCode='H' ProductType='ESN'></Product> <Product ProductCode='E' ProductType='OSE'></Product> <Product ProductCode='R' ProductType='NSE'></Product> <Product ProductCode='R' ProductType='ATA'></Product> <Product ProductCode='Y' ProductType='LLL'></Product> </Delivery> </Destination> <Destination City='Paris'> <Delivery> <Product ProductCode='B' ProductType='WHO'></Product> <Product ProductCode='A' ProductType='WAT'></Product> <Product ProductCode='G' ProductType='CHE'></Product> <Product ProductCode='E' ProductType='STH'></Product> <Product ProductCode='L' ProductType='WAT'></Product> <Product ProductCode='S' ProductType='CHM'></Product> </Delivery> </Destination> <Destination City='Munich'> <Delivery> <Product ProductCode='Q' ProductType='ENN'></Product> <Product ProductCode='U' ProductType='THE'></Product> <Product ProductCode='I' ProductType='SHA'></Product> <Product ProductCode='C' ProductType='DOW'></Product> <Product ProductCode='H' ProductType='KNO'></Product> <Product ProductCode='E' ProductType='WSS'></Product> </Delivery> </Destination> </Shipment>  "
    
            ' Load it
            Dim xDoc As XmlDocument = New XmlDocument()
            xDoc.LoadXml(DirtyHack(document))
    
            ' Required for string output
            Dim sb As StringBuilder = New StringBuilder()
            Dim writer As XmlWriter = XmlWriter.Create(sb)
    
            ' Do the transformation
            Dim tranny As XslCompiledTransform = New XslCompiledTransform()
            tranny.Load("c:\sandbox\MassageXML\Autobots.xslt")
            tranny.Transform(xDoc, writer)
    
            ' See what mess we've made
            Debug.WriteLine(sb.ToString)
    
        End Sub
    
        Function DirtyHack(ByVal inputString As String) As String
    
            Dim dict = New Dictionary(Of String, String)
    
            dict.Add("ProductCode='", "SortOrder='2' ProductCode='")
            dict.Add("SortOrder='2' ProductCode='R'", "SortOrder='1' ProductCode='R'")
            dict.Add("SortOrder='2' ProductCode='G'", "SortOrder='3' ProductCode='G'")
    
            For Each kvp As KeyValuePair(Of String, String) In dict
                inputString = inputString.Replace(kvp.Key, kvp.Value)
            Next
    
            Return inputString
    
        End Function
    
    End Module
    
    模块1
    副标题()
    "文件,
    将文档设置为字符串=“”
    “加载它
    Dim xDoc As XmlDocument=新XmlDocument()
    LoadXml(DirtyHack(文档))
    '对于字符串输出是必需的
    将某人调整为StringBuilder=新建StringBuilder()
    Dim writer As XmlWriter=XmlWriter.Create(sb)
    "转型"
    Dim tranny As XslCompiledTransform=新XslCompiledTransform()
    Load(“c:\sandbox\MassageXML\Autobots.xslt”)
    Transform(xDoc,编写器)
    “看看我们搞得多糟
    调试写线(某人写字符串)
    端接头
    函数DirtyHack(ByVal inputString作为String)作为String
    Dim dict=新字典(字符串、字符串)
    dict.Add(“ProductCode=”,“SortOrder='2'ProductCode=”)
    dict.Add(“SortOrder='2'产品代码='R'”,“SortOrder='1'产品代码='R'”)
    dict.Add(“SortOrder='2'产品代码='G'”,“SortOrder='3'产品代码='G'”)
    对于dict中的每个kvp作为KeyValuePair(字符串、字符串)的
    inputString=inputString.Replace(kvp.Key,kvp.Value)
    下一个
    返回输入字符串
    端函数
    端模块
    
    本质上,我在运行中添加了另一个属性,按此排序,然后删除它,但我确信一定有更干净的方法。有什么想法吗

    这是迄今为止的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:template match="@SortOrder" />
    
      <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
    
      <xsl:template match="Delivery">
        <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:apply-templates select="*">
            <xsl:sort select="@SortOrder" data-type="number" order="ascending"/>
          </xsl:apply-templates>
        </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    我的建议是,它将产品代码到数字排序值的映射定义为一个参数,并在
    xsl:sort
    中选择该参数,唯一的缺点是,在XSLT 1.0中,您需要
    exsl:node set
    msxsl:node set
    将参数所在的结果树片段转换为节点集,以便能够使用它,如图所示:

    <?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"
        xmlns:exsl="http://exslt.org/common"
        exclude-result-prefixes="msxsl exsl"
    >
    
        <xsl:output method="xml" indent="yes"/>
    
      <xsl:param name="sort-map-rtf">
          <map pc="R" sort="1"/>
          <map pc="G" sort="3"/>
          <map pc="*" sort="2"/>
      </xsl:param>
    
      <xsl:variable name="sort-map" select="exsl:node-set($sort-map-rtf)/map"/>
    
    
      <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
    
      <xsl:template match="Delivery">
        <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:apply-templates select="*">
            <xsl:sort select="($sort-map[@pc = current()/@ProductCode] | $sort-map[@pc = '*'])[1]/@sort" data-type="number" order="ascending"/>
          </xsl:apply-templates>
        </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    
    
    

    在线示例位于。

    能否将XML输入作为代码片段发布?否则,很难推荐一些经过测试的代码,因为没有要测试的输入数据。我认为您应该能够在XSLT中定义排序顺序,而无需首先操作XML输入。非常好-谢谢。我将研究exsl:节点集
    <?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:template match="@SortOrder" />
    
      <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
    
      <xsl:template match="Delivery">
        <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:apply-templates select="*">
            <xsl:sort select="@SortOrder" data-type="number" order="ascending"/>
          </xsl:apply-templates>
        </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    
    <?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"
        xmlns:exsl="http://exslt.org/common"
        exclude-result-prefixes="msxsl exsl"
    >
    
        <xsl:output method="xml" indent="yes"/>
    
      <xsl:param name="sort-map-rtf">
          <map pc="R" sort="1"/>
          <map pc="G" sort="3"/>
          <map pc="*" sort="2"/>
      </xsl:param>
    
      <xsl:variable name="sort-map" select="exsl:node-set($sort-map-rtf)/map"/>
    
    
      <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
    
      <xsl:template match="Delivery">
        <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:apply-templates select="*">
            <xsl:sort select="($sort-map[@pc = current()/@ProductCode] | $sort-map[@pc = '*'])[1]/@sort" data-type="number" order="ascending"/>
          </xsl:apply-templates>
        </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>