سؤال

لا يمكنني أن أكون أول شخص يقوم بذلك ، يبدو أنه سيكون من الممارسات الشائعة دمج مستندتين باستخدام XSLT. ومع ذلك ، لا يمكنني العثور على مثال واحد على in interweb.

لديّ اثنين من المستندات XML التي يتم استردادها كسلاسل من XML من SQL Server. أريد أن استخدام XslCompiledTransform لدمج الوثيقين. وأنا أعلم ذلك XslCompiledTransform يطفئ XSL document() وظيفة بشكل افتراضي. لقد حولت ذلك باستخدام XsltSettings عندما أقوم بإنشاء بلدي XslCompiledTransform هدف.

ما أفهمه حول كيفية "إضافة" المستند الثاني إلى التحول هو استخدام XsltArgumentList واستخدام AddParam() الطريقة وإضافة ملف XPathNavigator هدف:

XsltArgumentList xsltArgs = new XsltArgumentList();
xsltArgs.AddParam(
  (string)e.UserState + "s", "http://www.myuri.com/tabledata", 
  dataXmlDoc.CreateNavigator()
);

ومع ذلك ، فإن أي محاولات للوصول إلى المستند الذي يتم إضافته يؤدي إلى خطأ أو لا يتم إرجاع أي شيء. - ج#:

XslCompiledTransform fieldToXhtmlTransform = new XslCompiledTransform(true);
try
{
  UriBuilder xsltUri = new UriBuilder(
    Request.Url.Scheme, Request.Url.Host, 
    Request.Url.Port, this.ResolveUrl("Transforms/address1.xslt")
  );

  XmlSecureResolver resolver = new XmlSecureResolver(
    new XmlUrlResolver(), new PermissionSet(PermissionState.Unrestricted)
  );
  fieldToXhtmlTransform.Load(
    xsltUri.ToString(), new XsltSettings(true, false), resolver
  );
}
catch
{
  //TODO: do something useful here. 
}

XPathDocument fieldSchemaXmlDoc = null;

using (MemoryStream fieldMemoryStream = new MemoryStream(
  Encoding.UTF8.GetBytes(e.Result.TableMetaDataXml)
))
{
  fieldSchemaXmlDoc = new XPathDocument(fieldMemoryStream);
}

XPathDocument dataXmlDoc = null;

using (MemoryStream dataMemoryStream = new MemoryStream(
  Encoding.UTF8.GetBytes(e.Result.DataXml)
))
{
  dataXmlDoc = new XPathDocument(dataMemoryStream);
}

StringBuilder output = new StringBuilder();

XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.OmitXmlDeclaration = true;
writerSettings.Encoding = Encoding.UTF8;

XsltArgumentList xsltArgs = new XsltArgumentList();
xsltArgs.AddParam(
  (string)e.UserState + "s", "http://www.myuri.com/tabledata",
  dataXmlDoc.CreateNavigator()
);    
XmlWriter transformedDataWriter = XmlWriter.Create(output, writerSettings);
fieldToXhtmlTransform.Transform(
  fieldSchemaXmlDoc, xsltArgs, transformedDataWriter
);

XSLT - الوصول فقط إلى المستند المضافة ، وليس المستند المحمل بالتحويل.

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:hlsschema="http://www.myuri.com/tableschema"
  xmlns:hlsdata="http://www.myuri.com/tabledata"
  exclude-result-prefixes="msxsl hlsschema hlsdata xsl"
>
  <xsl:output method="html" indent="yes"/>

  <p>
  <xsl:template match="hlsdata:Address1s">
    <xsl:for-each select="hlsdata:Address1">
      <p>
        <xsl:value-of select="hlsdata:dr_id"/>
      </p>
    </xsl:for-each>
  </xsl:template>
  </p>

</xsl:stylesheet>

XML

<hlsdata:Address1s 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:hlsdata="http://www.myuri.com/tabledata"
>
  <hlsdata:Address1>
    <hlsdata:dr_id>12345678</hlsdata:dr_id>
  </hlsdata:Address1>
</hlsdata:Address1s>

أعلم أنني أفتقد شيئًا واضحًا ، لكنه يتجاوز الإحباط. أعلم أنه يتم إضافة المستند كمعلمة ، لكن لا يمكنني العثور على مثال على كيفية الوصول إلى مستند تم تحميله كمعلمة.

أي مساعدة سيكون موضع تقدير كبير. ضع في اعتبارك أن الكود أعلاه هو عمل مستمر وبين مئات المحاولات لجعله يعمل ، لذا إذا كان هناك شيء يبدو غريبًا بعض الشيء ، فربما يكون ذلك بسبب محاولاته.

هل كانت مفيدة؟

المحلول

تحتاج إلى تحديد معلمة في ورقة الأنماط الخاصة بك ثم استخدام هذه المعلمة. فيما يلي مثال بسيط ، يبدو أن ورقة الأنماط تبدو على النحو التالي:

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:docs="http://example.com/2010/docs"
  exclude-result-prefixes="docs"
>
  <xsl:param name="docs:doc1" select="/.."/>

  <xsl:template match="/">
    <xsl:apply-templates select="$docs:doc1/node()"/>
  </xsl:template>

  <xsl:template match="root">
    <ul>
      <xsl:apply-templates/>
    </ul>
  </xsl:template>

  <xsl:template match="foo">
    <li>
      <xsl:apply-templates/>
    </li>
  </xsl:template>
</xsl:stylesheet>

يبدو رمز C# على النحو التالي:

    string xml = "<root><foo>1</foo><foo>2</foo></root>";
    XPathDocument doc = new XPathDocument(new StringReader(xml));

    XslCompiledTransform proc = new XslCompiledTransform();
    proc.Load(@"..\..\XSLTFile1.xslt");

    XsltArgumentList xsltArgs = new XsltArgumentList();
    xsltArgs.AddParam("doc1", "http://example.com/2010/docs", doc.CreateNavigator());

    proc.Transform(XmlReader.Create(new StringReader("<dummy/>")), xsltArgs, Console.Out);

هذا تطبيق وحدة تحكم يكتب إلى Simplicity إلى Console.out ولكن يمكنك بالطبع استخدام المخرجات الأخرى التي تسمح بها طريقة التحويل.

هذا المثال يكتب ثم يكتب <ul><li>1</li><li>2</li></ul> لذلك تمت معالجة معلمة الإدخال.

لذلك يجب أن يوضح لك كيفية تمرير معلمة تعتبرها XSLcompileDTransform بمثابة مجموعة عقدة يمكنك معالجتها باستخدام XSLT.

أما بالنسبة لكتابة ورقة الأنماط التي تدمج مستندتين ، يرجى نشر عينتين إدخالين وعينة النتيجة المقابلة التي تريد إنشاءها إذا كان لديك مشاكل في كتابة XSLT.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top